3

クリック、テキスト フィールドのフォーカスなど、特定のページで Javascript イベントのボトルネックを見つけることを目指しています。

これを行うためのきちんとした方法があると強く確信していますが、それがクロスブラウザのものではないと思います. しかし、この時点では、どのブラウザー ベンダーがそのようなことを許可しているかは問題ではありません。

したがって、たとえば、すべての特定のイベント コールバックの呼び出しを無効にする方法が必要です。そのため、クリック イベントがトリガーされないようにする機能が必要です。それらの適切なブラウザー (Chrome、Firefox、Safari、Opera) のいずれかでそれは可能ですか? それがあれば、どのイベント タイプとどのイベント コールバックがボトルネックの原因であるかを特定する方法が得られるからです。

Chrome 開発者ツールの [スクリプト] タブを使用してイベント リスナー ブレークポイントを設定するように勧められる前に、特定のテキスト フィールドをクリックすると問題が発生することがわかりました (4 回のクリック コールバックがトリガーされ、明らかに多くのそこにイベントの委任があります)、しかし、ボトルネックの原因を正確に特定するために本当に正しいパスにいるかどうかを確認するために、ブラウザー レベルでクリック イベントを無効にしたいと考えています。

4

4 に答える 4

3

それを行うためのエレガントな方法はないと思います.1つの方法は、すべての要素を取得し、すべてのイベントバインディングをnullに設定するコードを少し書くことです.

var events = 'click change focus'.split(' '), // add more as needed
    eLen = events.length,
    eI = 0,
    els = document.getElementsByTagName('*'),
    len = els.length,
    i = 0,
    el;

for (; i < len; i++) {
    el = els[i];
    for (eI = 0; eI < eLen; eI++) {
        el['on' + events[eI]] = null;
    }
}
于 2012-04-13T13:24:52.067 に答える
1

これを攻撃する方法は、いくつかのグローバル変数の内容に基づいて、これらのイベントをアタッチしている関数をショートサーキットすることです。

そこにあるほとんどすべてのjsライブラリは、イベントハンドラーを関数にラップします。変数が設定されている場合、実際のリスナーの呼び出しをスキップするコードを少し追加するだけです。

いえ

var DO_NOT_FIRE = ['click', 'change'];

そして、ラップされたリスナーの内部:

// I'll just assume Array.prototype.indexOf is present for the sake of clarity
if(DO_NOT_FIRE.indexOf(eventType) == -1)
{
    originalListener.call(_this, evt);
}
于 2012-04-13T13:37:49.607 に答える
0

私はあなたが必要とすることをするjsfiddlerのサンプルを作りました..あなたはそれを他のタイプのイベントに拡張することができます..ジェームズ・ボンドほどエレガントではありませんが、トリックをします

基本的に、イベントが割り当てられているすべての要素を調べ、クリックイベントがあるかどうかを確認し(1つだけをチェックするため)、関数[...].click[0]を使用しますunbind

// some elements that I'll bind a click event handler through jquery
<input type="button" id="btn1" value="click 1" />
<input type="button" id="btn2" value="click 2" />
<input type="button" id="btn3" value="click 3" />​

// bind all buttons to some fake click handler
var btn_Click = function(e) {
    alert("clicked button " + $(this).attr("id")); 
};

$("input[type='button']").on("click", btn_Click);

// defining which events to block
var events_to_block = ['click'];

// filtering and unbinding the handler for click 

var x = document.getElementsByTagName("*");
$(x).each(function() {
    var x_events = $.data(this, 'events' );
    if(x_events !== undefined) { 
        if(-1 != events_to_block.indexOf("click")) {
            if((x_events.click !== undefined) && (x_events.click !== null)) {
                if($(this).attr("id") !== "btn2") {
                   $(this).unbind("click", x_events.click[0].handler);
                }
            }
        }
    }
});

PSbtn2 :デモンストレーションのためだけにイベントを保持するために2番目のボタン()を意図的に「許可」しました

于 2012-04-13T14:10:58.907 に答える
0

このリンクがあなたの問題を解決すると思います:

jQuery:すべてのクリックイベントを発生前にトラップしますか?

document.addEventListener('click', function(e) {
    e.stopPropagation();
}, true);

私はそれが行く方法だと思います

于 2012-04-13T13:28:27.620 に答える