1

クリックイベントにjQueryの関数を使用する必要がある状況があり$.fn.one()ますが、イベントの次の発生に適用したくない(通常のように)、その直後の発生に適用したい、次に自分自身のバインドを解除します(.one()通常のように)。

.one()最初のオカレンスに適用したくない理由documentは、バブリングフェーズの早い段階で呼び出されたイベントハンドラーからにバインドしているためです。そのため、最初にバブリングフェーズに到達するdocumentと、同じイベントの一部になります。次のクリックイベントがいつ発生するか知りたいです。

注:.stopPropagation()アプリの他の部分が破損する可能性があるため、使用したくありません。

これが私が思いついた2つのオプションですが、もっとエレガントな解決策があるはずです。

ダブルバインドメソッド:

$(document).one('click', function() {
  $(document).one('click', callback);
});

setTimeoutメソッド:

setTimeout(function() {
  $(document).one('click', callback);
}, 1);

どちらの方法も問題なく機能しますが、ここに私の質問があります。setTimeoutまたは頻繁なイベントのバインドとバインド解除のいずれかでパフォーマンスにどのような影響があるのか​​わかりません。誰か知っているなら、聞いてみたいです。しかし、もっと重要なことは、このような将来の状況のた​​めに、このようなものを自分で測定する方法についていくつかの提案が欲しいです。

私はhttp://jsperf.comのようなサイトが大好きですが、それがこのようなものを測定するのに本当に役立つかどうかはわかりません。

そして明らかに、誰かがはるかに優れた解決策を見た場合、私はそれを聞くのが大好きです。

4

1 に答える 1

1

ダブルバインド方式は非常にエレガントだと思います。実際の意図を正確に反映していると思います。必要なコードは2行だけです。

ただし、別のアプローチは、最初のイベントに関連付けられたイベントオブジェクトを.one()使用および更新するのではなく、コールバックが最初に呼び出されたときにコールバックが無視するようにフラグを追加することです。.on()

function oneCallback(e) {
    if (e.originalEvent.firstTimeIn)
        return;

    alert("This is the one after the current event");
    $(document).off("click", oneCallback);
}

$("div.source").click(function(e) {
    e.originalEvent.firstTimeIn = true;
    $(document).on("click", oneCallback);   
});

デモ: http: //jsfiddle.net/q5LG4/

event編集:オブジェクト(または所有していないオブジェクト)を変更しないことに関する懸念に対処するために、firstTimeフラグをクロージャーに格納できます。.oneAfterThis()これは、そのアプローチを採用するかなり危険なプラグインです。

jQuery.fn.oneAfterThis = function(eventName, callback) {
    this.each(function() {
        var first = true;
        function cb() {
            if(first){
                first = false;
                return;
            }
            callback.apply(this,[].slice.call(arguments));
            $(this).off(eventName,cb);
        }
        $(this).on(eventName, cb);
    });
};

$(someseletor).oneAfterThis("click", function() { ... });

それはもっとエレガントにできたと思いますが(おそらく、jQueryがどのように実装されているかを気にする必要がありました.one())、概念実証として何かをすばやく作成したかっただけです。

デモ: http: //jsfiddle.net/q5LG4/1/

于 2012-07-06T06:00:25.147 に答える