54

動的に生成されたすべての要素にイベントリスナー(Javascript)を追加することは可能ですか?私はページの所有者ではないため、静的な方法でリスナーを追加することはできません。

ページの読み込み時に作成されたすべての要素について、次を使用します。

doc.body.addEventListener('click', function(e){
//my code
},true);

ページに新しい要素が表示されたときにこのコードを呼び出すメソッドが必要ですが、jQueryを使用できません(delegate、onなどはプロジェクトで機能しません)。これどうやってするの?

4

8 に答える 8

80

図書館に頼らずに委任戦略を追求する必要があるようです。ここにいくつかのサンプルコードをフィドルに投稿しました:http://jsfiddle.net/founddrama/ggMUn/

その要点はtarget、オブジェクトでonを使用してevent、関心のある要素を探し、それに応じて応答することです。何かのようなもの:

document.querySelector('body').addEventListener('click', function(event) {
  if (event.target.tagName.toLowerCase() === 'li') {
    // do your action on your 'li' or whatever it is you're listening for
  }
});

警告!Fiddleの例には、標準に準拠したブラウザー(IE9 +、およびその他のほぼすべてのバージョン)のコードのみが含まれています。「古いIE」をサポートする必要がある場合attachEventは、独自のカスタムラッパーも提供する必要があります。適切なネイティブ関数。(これについては多くの良い議論があります。NicholasZakasが彼の著書Professional JavaScript for Web Developersで提供しているソリューションが好きです。)

于 2013-01-10T13:45:52.830 に答える
17

新しい要素を追加する方法によって異なります。

を使用して追加する場合はcreateElement、次のことを試すことができます。

var btn = document.createElement("button");
btn.addEventListener('click', masterEventHandler, false);
document.body.appendChild(btn);

次に、を使用masterEventHandler()してすべてのクリックを処理できます。

于 2013-01-10T13:28:26.267 に答える
3

ここで注目に値するあいまいな問題は、私が発見したばかりのこの事実かもしれません。

要素が以下にz-index設定されて-1いる場合、実際にはバインドされているのにリスナーがバインドされていないと思われるかもしれませんが、ブラウザはより高いz-index要素をクリックしていると見なします。

この場合の問題は、リスナーがバインドされていないことではなく、他の何か(たとえば、非表示の要素)が要素の上にあるため、フォーカスを取得できないことです。代わりにgetがフォーカスされます(つまり、イベントはトリガーされません)。幸い、要素を右クリックして[検査]を選択し、クリックしたものが「検査中」であるかどうかを確認することで、これを簡単に検出できます。

Chromeを使用していますが、他のブラウザがそれほど影響を受けているかどうかはわかりません。しかし、機能的には、リスナーがバインドされていないという問題にほとんどの点で似ているため、見つけるのは困難でした。CSSから次の行を削除して修正しました: z-index:-1;

于 2019-05-11T16:17:07.193 に答える
1

のような動的イベントリスナーを追加するための小さな関数を作成しましたjQuery.on()

受け入れられた回答と同じ考え方を使用しますがElement.matches()、ターゲットが指定されたセレクター文字列と一致するかどうかをチェックするメソッドを使用する点が異なります。

addDynamicEventListener(document.body, 'click', '.myClass, li', function (e) {
    console.log('Clicked', e.target.innerText);
});

githubからifを取得できます。

于 2017-06-29T12:08:51.410 に答える
1

「最新の」Webブラウザー(Microsoft Internet Explorerではない)のみをサポートする必要がある場合、ミューテーションオブザーバーはこのタスクに適したツールです。

new MutationObserver(function(mutationsList, observer) {
    for(const mutation of mutationsList) {
        if (mutation.type === 'childList') {
            // put your own source code here
        }
    }
}).observe(document.body, {childList: true, subtree: true});
于 2021-12-07T09:18:51.780 に答える
0

HTML elementsで動的に作成された匿名タスクの委任event.target.classList.contains('someClass')

  1. 返品trueまたはfalse
  2. 例えば。
let myEvnt = document.createElement('span');
myEvnt.setAttribute('class', 'someClass');
myEvnt.addEventListener('click', e => {
  if(event.target.classList.contains('someClass')){ 
    console.log(${event.currentTarget.classList})
}})
  1. 参照:https ://gomakethings.com/attaching-multiple-elements-to-a-single-event-listener-in-vanilla-js/
  2. 良い読み物:https ://eloquentjavascript.net/15_event.html#h_NEhx0cDpml
  3. MDN:https ://developer.mozilla.org/en-US/docs/Web/API/Event/Comparison_of_Event_Targets
  4. 挿入ポイント:
于 2018-07-29T10:05:50.260 に答える
0

このライブラリをご覧になることをお勧めします:https ://github.com/Financial-Times/ftdomdelegateこれは1,8Kgzipで圧縮されています

これは、登録時にDOMに何かが存在するかどうかに関係なく、指定されたセレクターに一致するすべてのターゲット要素のイベントにバインドするために作成されます。

スクリプトをインポートして、次のようにインスタンス化する必要があります。

  var delegate = new Delegate(document.body);
  delegate.on('click', 'button', handleButtonClicks);

  // Listen to all touch move
  // events that reach the body
  delegate.on('touchmove', handleTouchMove);

});


于 2019-11-01T14:43:14.637 に答える
-13

プロパティを使用classListして、一度に複数のクラスをバインドします

var container = document.getElementById("table");
container.classList.add("row", "oddrow", "firstrow");
于 2015-06-18T07:18:20.777 に答える