54

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

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

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

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

4

8 回答 8

80

听起来您需要在不退回图书馆的情况下采用委托策略。我在这里的小提琴中发布了一些示例代码:http: //jsfiddle.net/founddrama/ggMUn/

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

于 2013-01-10T13:45:52.830 回答
17

取决于您如何添加新元素。

如果你添加 using 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元素。

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

我用的是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

当您必须只支持“现代”网络浏览器(而不是 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

您可能想看看这个库:https ://github.com/Financial-Times/ftdomdelegate这是 1,8K gzipped

它用于绑定到与给定选择器匹配的所有目标元素上的事件,无论在注册时 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 回答
0

将匿名任务委托给动态HTML elements创建event.target.classList.contains('someClass')

  1. 返回truefalse
  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 回答
-13

使用classList属性一次绑定多个类

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