Javascript 在 NodeList 上添加事件监听器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12362256/
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
addEventListener on NodeList
提问by Dinesh P.R.
Does NodeList support addEventListener. If not what is the best way to add EventListener to all the nodes of the NodeList. Currently I am using the code snippet as show below, is there a better way to do this.
NodeList 是否支持 addEventListener。如果不是,将 EventListener 添加到 NodeList 的所有节点的最佳方法是什么。目前我正在使用如下所示的代码片段,有没有更好的方法来做到这一点。
var ar_coins = document.getElementsByClassName('coins');
for(var xx=0;xx < ar_coins.length;xx++)
{
ar_coins.item(xx).addEventListener('dragstart',handleDragStart,false);
}
回答by jfriend00
There is no way to do it without looping through every element. You could, of course, write a function to do it for you.
如果不循环遍历每个元素,就没有办法做到这一点。当然,您可以编写一个函数来为您执行此操作。
function addEventListenerList(list, event, fn) {
for (var i = 0, len = list.length; i < len; i++) {
list[i].addEventListener(event, fn, false);
}
}
var ar_coins = document.getElementsByClassName('coins');
addEventListenerList(ar_coins, 'dragstart', handleDragStart);
or a more specialized version:
或更专业的版本:
function addEventListenerByClass(className, event, fn) {
var list = document.getElementsByClassName(className);
for (var i = 0, len = list.length; i < len; i++) {
list[i].addEventListener(event, fn, false);
}
}
addEventListenerByClass('coins', 'dragstart', handleDragStart);
And, though you didn't ask about jQuery, this is the kind of stuff that jQuery is particularly good at:
而且,虽然您没有询问 jQuery,但这是 jQuery 特别擅长的东西:
$('.coins').on('dragstart', handleDragStart);
回答by Kris Selbekk
The best I could come up with was this:
我能想到的最好的办法是:
const $coins = document.querySelectorAll('.coins')
$coins.forEach($coin => $coin.addEventListener('dragstart', handleDragStart));
Note that this uses ES6 features, so please make sure to transpile it first!
请注意,这使用了 ES6 功能,因此请确保先将其转译!
回答by Multiversum
回答by Profesor08
The simplest example is to add this functionality to NodeList
最简单的例子是将此功能添加到 NodeList
NodeList.prototype.addEventListener = function (event_name, callback, useCapture)
{
for (var i = 0; i < this.length; i++)
{
this[i].addEventListener(event_name, callback, useCapture);
}
};
Now you can do:
现在你可以这样做:
document.querySelectorAll(".my-button").addEventListener("click", function ()
{
alert("Hi");
});
In the same way, you can do a forEach
loop
同样的方式,你可以做一个forEach
循环
NodeList.prototype.forEach = function (callback)
{
for (var i = 0; i < this.length; i++)
{
callback(this[i], i);
}
};
Using:
使用:
document.querySelectorAll(".buttons").forEach(function (element, id)
{
input.addEventListener("change", function ()
{
alert("button: " + id);
});
});
EDIT: note that NodeList.prototype.forEach has existed ever since november 2016 in FF. No IE support though
编辑:请注意 NodeList.prototype.forEach 自 2016 年 11 月以来在 FF 中一直存在。虽然没有 IE 支持
回答by Darlan Mendon?a
in es6, you can do a array from nodelist, using Array.from, e.g.
在 es6 中,您可以使用 Array.from 从节点列表中创建一个数组,例如
ar_coins = document.getElementsByClassName('coins');
Array
.from(ar_coins)
.forEach(addEvent)
function addEvent(element) {
element.addEventListener('click', callback)
}
or just use arrow functions
或者只使用箭头函数
Array
.from(ar_coins)
.forEach(element => element.addEventListener('click', callback))
回答by Duncan
I suppose another option would be to define addEventListener
on NodeList
using Object.defineProperty
. That way you can treat the NodeList as you would a single Node.
我想,另一种选择是定义addEventListener
上NodeList
使用Object.defineProperty
。这样你就可以像对待单个节点一样对待 NodeList。
As an example, I created a jsfiddle here: http://jsfiddle.net/2LQbe/
例如,我在这里创建了一个 jsfiddle:http: //jsfiddle.net/2LQbe/
The key point is this:
关键是这样的:
Object.defineProperty(NodeList.prototype, "addEventListener", {
value: function (event, callback, useCapture) {
useCapture = ( !! useCapture) | false;
for (var i = 0; i < this.length; ++i) {
if (this[i] instanceof Node) {
this[i].addEventListener(event, callback, useCapture);
}
}
return this;
}
});
回答by user414873
Another solution is to use event-delegation. You just add an eventlistener to the closets parent of the ".coins" and use event.target in the callback to check if the click was really on an element with the class "coins".
另一种解决方案是使用事件委托。您只需将事件侦听器添加到“.coins”的壁橱父项,并在回调中使用 event.target 来检查单击是否真的位于具有“coins”类的元素上。
回答by Jon Allen
You could also use prototyping
你也可以使用原型
NodeList.prototype.addEventListener = function (type, callback) {
this.forEach(function (node) {
node.addEventListener(type, callback);
});
};