Javascript 在动态创建的元素上添加事件侦听器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14258787/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
add event listener on elements created dynamically
提问by jenjis
Is possible to add event listener (Javascript) to all dynamically generated elements? I'm not the owner of the page, so I cannot add a listener in a static way.
是否可以向所有动态生成的元素添加事件侦听器 (Javascript)?我不是该页面的所有者,因此我无法以静态方式添加侦听器。
For all the elements created when the page loaded I use:
对于加载页面时创建的所有元素,我使用:
doc.body.addEventListener('click', function(e){
//my code
},true);
I need a method to call this code when new elements appear on the page, but I cannot use jQuery (delegate, on, etc cannot work in my project). How can I do this?
当新元素出现在页面上时,我需要一种方法来调用此代码,但我无法使用 jQuery(delegate、on 等无法在我的项目中工作)。我怎样才能做到这一点?
回答by founddrama
It sounds like you need to pursue a delegation strategy without falling back to a library. I've posted some sample code in a Fiddle here: http://jsfiddle.net/founddrama/ggMUn/
听起来您需要在不退回到图书馆的情况下采用委托策略。我在这里的 Fiddle 中发布了一些示例代码:http: //jsfiddle.net/founddrama/ggMUn/
The gist of it is to use the targeton the eventobject to look for the elements you're interested in, and respond accordingly. Something like:
它的要点是使用对象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
}
});
CAVEATS!The example Fiddle only includes code for the standards-compliant browsers (i.e., IE9+, and pretty much every version of everyone else) If you need to support "old IE's" attachEvent, then you'll want to also provide your own custom wrapper around the proper native functions. (There are lots of good discussions out there about this; I like the solution Nicholas Zakas provides in his book Professional JavaScript for Web Developers.)
注意事项!示例 Fiddle 仅包含符合标准的浏览器(即 IE9+,以及几乎所有其他版本的所有版本)的代码 如果您需要支持“旧 IE” attachEvent,那么您还需要提供自己的自定义包装器适当的本机功能。(关于这个有很多很好的讨论;我喜欢 Nicholas Zakas 在他的书Professional JavaScript for Web Developers 中提供的解决方案。)
回答by ATOzTOA
Depends on how you add new elements.
取决于您如何添加新元素。
If you add using createElement, you can try this:
如果你添加 using createElement,你可以试试这个:
var btn = document.createElement("button");
btn.addEventListener('click', masterEventHandler, false);
document.body.appendChild(btn);
Then you can use masterEventHandler()to handle all clicks.
然后你可以用它masterEventHandler()来处理所有的点击。
回答by XCS
I have created a small function to add dynamic event listeners, similar to jQuery.on().
我创建了一个小函数来添加动态事件侦听器,类似于jQuery.on().
It uses the same idea as the accepted answer, only that it uses the Element.matches()method to check if the target matches the given selector string.
它使用与接受的答案相同的想法,只是它使用该Element.matches()方法来检查目标是否与给定的选择器字符串匹配。
addDynamicEventListener(document.body, 'click', '.myClass, li', function (e) {
console.log('Clicked', e.target.innerText);
});
You can get if from github.
你可以从 github得到 if 。
回答by Vipul Anand
Delegating the anonymous task to dynamically created HTMLelementswith event.target.classList.contains('someClass')
将匿名任务委托给动态创建HTMLelements的event.target.classList.contains('someClass')
- returns
trueorfalse - eg.
- 返回
true或false - 例如。
let myEvnt = document.createElement('span');
myEvnt.setAttribute('class', 'someClass');
myEvnt.addEventListener('click', e => {
if(event.target.classList.contains('someClass')){
console.log(${event.currentTarget.classList})
}})
回答by elliott954
An obscure problem worth noting here may also be this fact I just discovered:
这里值得注意的一个模糊问题也可能是我刚刚发现的这个事实:
If an element has
z-indexset to-1or smaller, you may think the listener is not being bound, when in fact it is, but the browser thinks you are clicking on a higherz-indexelement.
如果某个元素
z-index设置为-1或更小,您可能会认为侦听器没有被绑定,但实际上是这样,但浏览器认为您正在单击更高的z-index元素。
The problem, in this case, is not that the listener isn't bound, but instead it isn't able to get the focus, because something else (e.g., perhaps a hidden element) is on top of your element, and that what get's the focus instead (meaning: the event is not being triggered). Fortunately, you can detect this easily enough by right-clicking the element, selecting 'inspect' and checking to see if what you clicked on is what is being "inspected".
在这种情况下,问题不是侦听器没有被绑定,而是它无法获得焦点,因为其他东西(例如,可能是隐藏元素)在您的元素之上,并且get 是焦点(意思是:事件没有被触发)。幸运的是,您可以通过右键单击元素,选择“检查”并检查您单击的内容是否正在“检查”来轻松检测到这一点。
I am using Chrome, and I don't know if other browsers are so affected. But, it was hard to find because functionally, it resembles in most ways the problem with the listener not being bound. I fixed it by removing from CSS the line: z-index:-1;
我用的是Chrome,不知道其他浏览器有没有这么受影响。但是,很难找到,因为在功能上,它在大多数方面都类似于侦听器没有被绑定的问题。我固定它通过CSS删除行: z-index:-1;
回答by Nasia Makrygianni
You might wanna take a look at this library: https://github.com/Financial-Times/ftdomdelegatewhich is 1,8K gzipped
你可能想看看这个库:https: //github.com/Financial-Times/ftdomdelegate这是 1,8K gzipped
It is made for binding to events on all target elements matching the given selector, irrespective of whether anything exists in the DOM at registration time or not.
它用于绑定到与给定选择器匹配的所有目标元素上的事件,无论在注册时 DOM 中是否存在任何内容。
You need to import the script and then instantiate it like that:
您需要导入脚本,然后像这样实例化它:
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);
});
回答by Rakesh Gupta
Use classListproperty to bind more than one class at a time
使用classList属性一次绑定多个类
var container = document.getElementById("table");
container.classList.add("row", "oddrow", "firstrow");

