Javascript 在动态创建的元素上添加事件侦听器

Javascript 在动态创建的元素上添加事件侦听器,javascript,addeventlistener,dom-events,intercept,Javascript,Addeventlistener,Dom Events,Intercept,是否可以向所有动态生成的元素添加事件侦听器(Javascript)? 我不是页面的所有者,因此无法以静态方式添加侦听器 对于加载页面时创建的所有元素,我使用: doc.body.addEventListener('click', function(e){ //my code },true); 当页面上出现新元素时,我需要一个方法来调用此代码,但我不能使用jQuery(委托、打开等不能在我的项目中工作)。我如何才能做到这一点?取决于如何添加新元素 如果使用createElement添加,可以尝试

是否可以向所有动态生成的元素添加事件侦听器(Javascript)? 我不是页面的所有者,因此无法以静态方式添加侦听器

对于加载页面时创建的所有元素,我使用:

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

当页面上出现新元素时,我需要一个方法来调用此代码,但我不能使用jQuery(委托、打开等不能在我的项目中工作)。我如何才能做到这一点?

取决于如何添加新元素

如果使用
createElement
添加,可以尝试以下操作:

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

然后,您可以使用
masterEventHandler()
来处理所有单击。

听起来您需要执行委派策略,而不必退回到库中。我在这里发布了一些示例代码:

其要点是使用
事件
对象上的
目标
查找您感兴趣的元素,并做出相应的响应。比如:

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
,那么您还需要围绕适当的本机函数提供您自己的自定义包装。(关于这一点有很多很好的讨论;我喜欢Nicholas Zakas在他的书《面向Web开发人员的专业JavaScript》中提供的解决方案。)

使用
类列表
属性一次绑定多个类

var container = document.getElementById("table");
container.classList.add("row", "oddrow", "firstrow");

我创建了一个小函数来添加动态事件侦听器,类似于
jQuery.on()

它使用与接受答案相同的方法,只是使用
元素.matches()
方法检查目标是否与给定的选择器字符串匹配

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

如果。

将匿名任务委托给使用
event.target.classList.contains('someClass')动态创建的
HTML
元素,则可以获得

  • 返回
    true
    false
  • 例如
  • 参考:
  • 好书:
  • MDN:
  • 插入点:

  • 这里值得注意的一个模糊问题可能也是我刚刚发现的一个事实:

    如果某个元素的z索引设置为
    -1
    或更小,您可能会认为 侦听器并没有被绑定,实际上是被绑定的,而是浏览器 认为您正在单击更高的
    z-index
    元素

    在这种情况下,问题不在于监听器没有绑定,而是它无法获得焦点,因为其他东西(例如,一个隐藏的元素)在元素的顶部,而获得的是焦点(意思是:事件没有被触发)。幸运的是,您可以通过右键单击元素、选择“检查”并检查您单击的内容是否是正在“检查”的内容来很容易地检测到这一点


    我使用的是Chrome浏览器,我不知道其他浏览器是否受到如此大的影响。但是,这很难找到,因为在功能上,它在大多数方面类似于听者不受约束的问题。我通过从CSS中删除以下行来修复它:
    z-index:-1

    您可能想看看这个库:它是1,8K gzip

    它用于绑定到与给定选择器匹配的所有目标元素上的事件,而不管注册时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);
    
    });
    
    
    

    我不是添加元素的页面的所有者,所以我不知道元素的插入方式。到目前为止,这是最好的答案。@JianWeihang你能澄清你的问题吗?您不希望将该元素直接应用于
    主体
    元素(例如,作为
    onclick
    属性),否则可能会使已有的侦听器崩溃。事件委派策略更安全:不太可能干扰或撞击元素上的其他侦听器,也不太可能占用每个元素侦听器的内存。很好的答案,我想知道的不仅仅是
    document.body==document.querySelector('body')
    ?这就是为什么在这两种情况下,您总是只将一个单击处理程序附加到一个body元素上。@drinchev是的,这两个元素是等效的。在给出示例时,我更喜欢使用
    document.querySelector()
    版本,因为这样更容易概括——也就是说,不是每个元素都可以作为属性从
    文档中访问。如果我的事件是
    focus
    ,它似乎不起作用。我该怎么办?@ColorWin您需要使用。事件侦听器不是类。
      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);
    
    });