是否有一种纯粹的 Javascript 方法可以将一个函数应用于多个元素的事件?
Is there a pure Javascript way to apply one function to multiple element's events?
我想使用纯 Javascript.
将单个函数绑定到多个事件
在 jQuery 我会使用:
$('.className').click(function(e){ //do stuff });
所以我尝试使用纯 JS:
document.getElementsByClassName('className').onclick = function(e){ //do stuff };
这不起作用,因为 getElementsByClassName
returns 一个数组,而不是 DOM 对象。
我可以遍历数组,但这似乎过于冗长而且似乎没有必要:
var topBars = document.getElementsByClassName('className');
for(var i = 0; i < topBars.length; i++){
topBars[i].onclick = function(e){ //do stuff };
}
是否有一种标准方法可以使用纯 Javascript 来完成此操作?
var elems = document.querySelectorAll('.className');
var values = Array.prototype.map.call(elems, function(obj) {
return obj.onclick = function(e){ //do stuff };
});
这个(改编自 MDN 的例子)是你如何在没有传统循环的情况下做到这一点的。
您可以将事件处理程序添加到父元素,然后确定是否单击了具有所需 class 名称的子元素之一:
var parent = document.getElementById('parent');
parent.addEventListener('click', function (e) {
if ((' ' + e.target.className + ' ').indexOf(' item ') !== -1) {
// add logic here
console.log(e.target);
}
});
或...
var parent = document.getElementById('parent');
parent.addEventListener('click', function (e) {
Array.prototype.forEach.call(parent.querySelectorAll('.item'), function (el) {
if (el === e.target) {
// add logic here
console.log(e.target);
}
});
});
只有当您单击具有指定 class 的元素时,以上代码片段才会起作用。换句话说,如果您单击该给定元素的子元素,它将不起作用。要解决此问题,您可以使用以下方法:
var parent = document.getElementById('parent');
parent.addEventListener('click', function (e) {
var target = e.target; // Clicked element
while (target && target.parentNode !== parent) {
target = target.parentNode; // If the clicked element isn't a direct child
if (!target) { return; } // If element doesn't exist
}
if ((' ' + target.className + ' ').indexOf(' item ') !== -1){
// add logic here
console.log(target);
}
});
var parent = document.getElementById('parent');
parent.addEventListener('click', function (e) {
var target = e.target; // Clicked element
while (target && target.parentNode !== parent) {
target = target.parentNode; // If the clicked element isn't a direct child
if (!target) { return; } // If element doesn't exist
}
Array.prototype.forEach.call(parent.querySelectorAll('.item'), function (el) {
if (el === target) {
// add logic here
console.log(target);
}
});
});
作为 hack,其中 DOM 是使用原型继承模型(大多数浏览器但不是全部)实现的,您可以向 NodeList 构造函数添加迭代器:
if (NodeList && NodeList.prototype && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = function(callback, thisArg) {
Array.prototype.forEach.call(this, callback, thisArg)
}
}
然后:
document.getElementsByClassName('item').forEach(function(el){
el.addEventListener('click', someFn, false);
})
或
document.querySelectorAll('.item').forEach(function(el){
el.addEventListener('click', someFn, false);
})
当然你不应该在网络上的生产环境中这样做(don't mess with host objects 等等),但如果可以的话不是很好吗?或者迭代器被添加到 DOM 列表和集合?
我想使用纯 Javascript.
将单个函数绑定到多个事件在 jQuery 我会使用:
$('.className').click(function(e){ //do stuff });
所以我尝试使用纯 JS:
document.getElementsByClassName('className').onclick = function(e){ //do stuff };
这不起作用,因为 getElementsByClassName
returns 一个数组,而不是 DOM 对象。
我可以遍历数组,但这似乎过于冗长而且似乎没有必要:
var topBars = document.getElementsByClassName('className');
for(var i = 0; i < topBars.length; i++){
topBars[i].onclick = function(e){ //do stuff };
}
是否有一种标准方法可以使用纯 Javascript 来完成此操作?
var elems = document.querySelectorAll('.className');
var values = Array.prototype.map.call(elems, function(obj) {
return obj.onclick = function(e){ //do stuff };
});
这个(改编自 MDN 的例子)是你如何在没有传统循环的情况下做到这一点的。
您可以将事件处理程序添加到父元素,然后确定是否单击了具有所需 class 名称的子元素之一:
var parent = document.getElementById('parent');
parent.addEventListener('click', function (e) {
if ((' ' + e.target.className + ' ').indexOf(' item ') !== -1) {
// add logic here
console.log(e.target);
}
});
或...
var parent = document.getElementById('parent');
parent.addEventListener('click', function (e) {
Array.prototype.forEach.call(parent.querySelectorAll('.item'), function (el) {
if (el === e.target) {
// add logic here
console.log(e.target);
}
});
});
只有当您单击具有指定 class 的元素时,以上代码片段才会起作用。换句话说,如果您单击该给定元素的子元素,它将不起作用。要解决此问题,您可以使用以下方法:
var parent = document.getElementById('parent');
parent.addEventListener('click', function (e) {
var target = e.target; // Clicked element
while (target && target.parentNode !== parent) {
target = target.parentNode; // If the clicked element isn't a direct child
if (!target) { return; } // If element doesn't exist
}
if ((' ' + target.className + ' ').indexOf(' item ') !== -1){
// add logic here
console.log(target);
}
});
var parent = document.getElementById('parent');
parent.addEventListener('click', function (e) {
var target = e.target; // Clicked element
while (target && target.parentNode !== parent) {
target = target.parentNode; // If the clicked element isn't a direct child
if (!target) { return; } // If element doesn't exist
}
Array.prototype.forEach.call(parent.querySelectorAll('.item'), function (el) {
if (el === target) {
// add logic here
console.log(target);
}
});
});
作为 hack,其中 DOM 是使用原型继承模型(大多数浏览器但不是全部)实现的,您可以向 NodeList 构造函数添加迭代器:
if (NodeList && NodeList.prototype && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = function(callback, thisArg) {
Array.prototype.forEach.call(this, callback, thisArg)
}
}
然后:
document.getElementsByClassName('item').forEach(function(el){
el.addEventListener('click', someFn, false);
})
或
document.querySelectorAll('.item').forEach(function(el){
el.addEventListener('click', someFn, false);
})
当然你不应该在网络上的生产环境中这样做(don't mess with host objects 等等),但如果可以的话不是很好吗?或者迭代器被添加到 DOM 列表和集合?