addEventListener用于新元素

时间:2012-06-24 17:56:28

标签: javascript javascript-events addeventlistener

将基本addEventListener视为

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

原始文档中不存在<div id="alert">ALERT</div>,我们通过AJAX从外部源调用它。我们如何强制addEventListener为文档中新添加的元素工作(在window.onload初始扫描DOM元素之后)?

在jQuery中,我们通过live()delegate()执行此操作;但我们如何在纯Javascript中使用addEventListener来做到这一点?事实上,我正在寻找与delegate()相当的,因为live()将事件附加到根文档;我希望在parent的水平上进行新的活动。

2 个答案:

答案 0 :(得分: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 );
};

你对此缺失的是:

  • 性能优化,每个委托侦听器都会运行一个完整的循环,所以如果你在一个元素上添加很多,你将运行所有这些循环
  • 可写事件对象。因此,您无法修复e.currentTarget这非常重要,因为this通常用作对某个实例的引用
  • 没有数据存储实现,因此除非您每次都手动创建函数,否则没有好的方法可以删除处理程序
  • 仅支持冒泡事件,因此没有使用jQuery认为理所当然的"change""submit"
  • 我现在暂时忘记了许多其他人

答案 1 :(得分:2)

document.addEventListener("DOMNodeInserted", evtNewElement, false);

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

注意:根据@hemlock的评论,似乎不推荐使用这一系列事件。我们必须改为mutation observers