4

基本addEventListenerを次のように考えてください。

window.onload=function(){
  document.getElementById("alert")
  .addEventListener('click', function(){
     alert("OK");
  }, false);
}

where<div id="alert">ALERT</div>は元のドキュメントには存在せず、AJAX によって外部ソースから呼び出します。ドキュメントに新しく追加された要素を強制的に処理するにはどうすればよいでしょうかaddEventListener( による DOM 要素の最初のスキャンの後window.onload)。

jQuery では、これをlive()orで行いdelegate()ます。addEventListenerしかし、純粋なJavascriptでこれを行うにはどうすればよいでしょうか? 実際のところ、イベントをルートドキュメントに添付するためdelegate()、に相当するものを探しています。live()のレベルで聴ける新鮮なイベントを作りたいと思っていますparent

4

2 に答える 2

5

非常に単純化されており、jQuery のイベント システムとはかけ離れていますが、基本的な考え方はそこにあります。

http://jsfiddle.net/fJzBL/

var div = document.createElement("div"),
    prefix = ["moz","webkit","ms","o"].filter(function(prefix){
         return prefix+"MatchesSelector" in div;
    })[0] + "MatchesSelector";

Element.prototype.addDelegateListener = function( type, selector, fn ) {

    this.addEventListener( type, function(e){
        var target = e.target;

        while( target && target !== this && !target[prefix](selector) ) {
            target = target.parentNode;
        }

        if( target && target !== this ) {
            return fn.call( target, e );
        }

    }, false );
};

これで欠けているもの:

  • パフォーマンスの最適化。すべてのデリゲート リスナーが完全なループを実行するため、1 つの要素に多数のリスナーを追加すると、これらすべてのループが実行されます。
  • 書き込み可能なイベント オブジェクト。したがって、通常はインスタンスへの参照として使用されるため、e.currentTargetどれが非常に重要かを修正することはできませんthis
  • データストアの実装がないため、毎回関数を手動で作成しない限り、ハンドラーを削除する良い方法はありません
  • バブリングイベントのみがサポートされているため、jQuery で当然と考えられていた"change"or etc はありません"submit"
  • 私が今のところ単に忘れている他の多くの
于 2012-06-24T18:22:15.637 に答える
2
document.addEventListener("DOMNodeInserted", evtNewElement, false);

function evtNewElement(e) {
    try {
        switch(e.target.id) {
            case 'alert': /* addEventListener stuff */ ; break;
            default: /**/
        }
    } catch(ex) {}
}

注: @hemlock のコメントによると、この一連のイベントは推奨されていないようです。代わりに、突然変異オブザーバーに向かわなければなりません。

于 2012-06-24T17:59:57.753 に答える