addEventListener on NodeList
addEventListener on NodeList
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);
}
如果不循环遍历每个元素,就无法做到这一点。当然,你可以写一个函数来为你做这件事。
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);
或者更专业的版本:
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);
而且,虽然你没有问过jQuery,但这正是jQuery特别擅长的东西:
$('.coins').on('dragstart', handleDragStart);
我能想到的最好的办法是:
const $coins = document.querySelectorAll('.coins')
$coins.forEach($coin => $coin.addEventListener('dragstart', handleDragStart));
请注意,这使用了ES6功能,所以请确保先将其转换!
实际上有一种方法可以在没有循环的情况下完成:
[].forEach.call(nodeList,function(e){e.addEventListener('click',callback,false)})
这种方法被用于我的一个单行辅助库nanoQuery中。
最简单的例子是将此功能添加到NodeList
NodeList.prototype.addEventListener = function (event_name, callback, useCapture)
{
for (var i = 0; i < this.length; i++)
{
this[i].addEventListener(event_name, callback, useCapture);
}
};
现在你可以做:
document.querySelectorAll(".my-button").addEventListener("click", function ()
{
alert("Hi");
});
用同样的方法,你可以做一个forEach
循环
NodeList.prototype.forEach = function (callback)
{
for (var i = 0; i < this.length; i++)
{
callback(this[i], i);
}
};
使用:
document.querySelectorAll(".buttons").forEach(function (element, id)
{
input.addEventListener("change", function ()
{
alert("button: " + id);
});
});
EDIT:请注意,NodeList.prototype.forEach自2016年11月以来一直存在于FF中。尽管
在es6中,您可以使用array.from从nodelist中创建数组,例如
ar_coins = document.getElementsByClassName('coins');
Array
.from(ar_coins)
.forEach(addEvent)
function addEvent(element) {
element.addEventListener('click', callback)
}
或者只使用箭头功能
Array
.from(ar_coins)
.forEach(element => element.addEventListener('click', callback))
另一个解决方案是使用事件委派。您只需将addEventListener
用于.coins
元素的最近父元素,并在回调中使用event.target
来检查单击是否真的在类为"coins"
的元素上。
我想另一个选项是使用Object.defineProperty
在NodeList
上定义addEventListener
。这样,您就可以像对待单个节点一样对待NodeList。
例如,我在这里创建了一个jsfiddle:http://jsfiddle.net/2LQbe/
关键是:
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;
}
});
您也可以使用原型
NodeList.prototype.addEventListener = function (type, callback) {
this.forEach(function (node) {
node.addEventListener(type, callback);
});
};
相关文章:
- 使用 jQuery 的 .on 函数如何获取事件的原始元素
- I'我设计了一个下拉菜单,onclick会出现,而on blur会消失
- window.on.scroll事件未启动
- Socket.io on Mozilla Rhino
- CSS中的游标属性似乎不适用于USB On The Go
- jQuery点击ON现在使用.load触发关闭
- JQuery.on(“keydown”)追加到页面时不工作
- 使用.on动态添加jquery/js不知道的html元素
- angularjs$valid-on-dates在firefox中报告错误
- addEventListener on NodeList
- 当我在节点上拖动鼠标时,我如何防止使用d3.ehavior.zoom().on(“缩放”,重绘)
- jQuery 1.7.2:.on()在一个页面上工作;Don’别再干别的了
- Jquery on单击“显示信息”
- 平均值.on(事件[,选择器][,数据],处理程序)
- 多个jQuery.on()事件无法运行xBrowser(取决于顺序)
- 如何使jQuery的“bind”或“on”事件处理程序幂等
- 无法使以下ng on click outside指令在同一页面上的两个元素上工作
- Javascript mozfullscreenchange on Firefox
- iframe and JavaScript on different pages
- Q.all on NodeList in Node