3

ですから、これは非常に単純な質問かもしれませんが、とにかく質問します。そして、これは明らかに、これら2つのステートメントがどのように機能するかを私の心の中で明確にするためのものです。

シナリオAjaxを介してプルしているJSONを呼び出し、それをいくつかのセレクターを持つhtmlに補間します。このような:

$.each(r, function(k,v){
  str+='location: <div class=\'loc-to-select\' data-location-id=\'' + v.id +  '\'>';
  str+= v.name + '</div>';
});
$('#event-search-locations').html(str);

基本的に書き出す:

<div class='loc-to-select' data-location-id='2'>Joe's</div>

私はこれらの2つのjQueryを持っています:

// doesn't work
$('.loc-to-select').on('click',function(){
  alert('here you go');
});

// does work
$(document).on('click','.loc-to-select', function(){
  alert('here you go');
});

これはすべて、jQueryの$(document).readyの起動が終了した後に明らかに行われます。これがjQueryが提供する主な機能であると私は理解しています。私はイベントバブリングの概念に精通しています。また、ここhttp://api.jquery.com/on/ で、委任されたイベントについて説明しているドキュメントを読みました。私は、jQueryが子孫要素を介してこれをどのように行っているかを内部的に理解していません。これのいくつかは、それがユーザースペースpovからどのように処理するかを議論します:直接対委任-jQuery .on()

また、パフォーマンス上の理由から、子孫要素手法が好まれているようです。子孫要素モデルは基本的に、DOMに何か新しいものが追加された場合、それが「委任された要素」モデルに準拠しているかどうかを確認しますが、直接イベントはこれをバイパスしますか?

より単純なレベルでは、jQueryの「ランタイム」は基本的にDOMの変更を監視してからチェックしますか、それともたとえばhtml関数(基本的にはhtmlを介して認識しているアイテムを解析します)でチェックしますか?

最後に、なぜ2番目の構文(委任された構文)をデフォルトにしないのですか?(ドキュメントに記載されているように)より高い特異性とより良いパフォーマンスを提供するように思われます

どうも

4

1 に答える 1

3

あなたがリンクした質問(直接対委任-jQuery .on())はあなたが求めているものに対する答えを持っているように見えるので、私はあなたが知りたいことを100%確信していません。

ここでも違いの説明があります:

$('.loc-to-select').on('click',function(){
  alert('here you go');
});

その時点.loc-to-selectで存在するすべての要素を検索し、イベントハンドラーをこれらの各要素にバインドします。

DOMAPIを使用した場合の同等の機能は次のとおりです。

var elements = document.getElementsByClassName('loc-to-select');
for(var i = 0, l = elements.length; i < l; i++) {
    elements[i].onclick = handler;
}

今考えてみましょう

$(document).on('click','.loc-to-select', function(){
  alert('here you go');
});

1つのイベントハンドラーのみをにバインドしdocumentます。すべてのクリックイベントを検査し、それがクラスの要素から発生したのか、要素内で発生したのかをテストしますloc-to-select

繰り返しますが、DOMに相当するもの(簡略化):

document.body.onclick = function(event) {
    if(event.target.className === 'loc-to-select') {
         handler.call(this);
    }
}

jQueryはDOMの変更を監視せず、イベントがツリーをバブリングしているという事実を使用するだけです。

最後に、なぜ2番目の構文(委任された構文)をデフォルトにしないのですか?(ドキュメントに記載されているように)より高い特異性とより良いパフォーマンスを提供するように思われます

イベント委任で何が起こるかをもう一度要約してみましょう。単一のイベントハンドラーが1つの要素にバインドされ、複数の(類似した)要素を処理します。つまり、要素を処理するために必要なのは検索要素とタッチ要素だけです。xつまり、設定が高速です。yx << y

ただし、トレードオフがあります。イベントは最初にツリーをトラバースし、発生元を評価する必要があるため、一致するかどうかに関係なく、発生したイベントの処理に時間がかかります。ページ上のすべてのクリックイベントに
イベント委任を使用し、ハンドラーをにバインドするとどうなるかを考えてください。最終的にはにバインドされたイベントハンドラーになり、それぞれがシングルクリックで実行されます。しかし、それらのうち、実行する必要があるのは1つだけです。これはあまりパフォーマンスが良くないようです。documentndocumentn

直接イベント処理を使用すると、すべての要素を見つけてイベントハンドラーを各要素にバインドする必要があるため、セットアップが遅くなります。要素が多くない場合は問題ありませんが、要素が多い場合は問題になる可能性があります。どうやらブラウザは、バインドされているイベントハンドラが多いほどパフォーマンスが低下しますが、変更されるか、すでに変更されている可能性があります。

これは、多数の要素にバインドされた多数のイベントハンドラーの実行回数を減らすことと、少数の要素にバインドされた少数のイベントハンドラーを何度も実行することの間のトレードオフです。

于 2012-08-15T15:55:28.247 に答える