forEach 方法不起作用
forEach method does not work
HTML:
<input type="button" value="Start" id="start">
JavaScript:
var inp = document.querySelectorAll('.z1');
Array.prototype.forEach.call(inp, function(item, i, arr) {
item[i].addEventListener('click', function() {
alert('fsdfs');
}, false);
});
document.getElementById('start').addEventListener('click',function() {
var gg = '<input type="button" value="Button1" class="z1"><input type="button" value="Button2" class="z1">';
document.body.insertAdjacentHTML('beforeEnd', gg);
});
这个想法是当你点击插入正文中的 INPUT 时应该触发警报。
不会为新元素触发警报,因为您从未将事件绑定到它们。而是将点击事件委托给主体,它最终会在主体中冒泡:
document.body.addEventListener('click', function(e) {
if (e.target.className == 'z1') {
alert('fsdfs');
}
}, false);
document.getElementById('start').addEventListener('click',function() {
var gg = '<input type="button" value="Button1" class="z1"><input type="button" value="Button2" class="z1">';
document.body.insertAdjacentHTML('beforeEnd', gg);
});
<input type="button" value="Start" id="start">
请记住,在委托事件的情况下,您需要检查事件是否发生在正确的元素上。就像在演示中一样,您可以检查事件目标 class name.
您的 selector 将 select 与您显示的 HTML 没有任何关系,但是,如果您的 selector 正在工作,那么这是正确的代码
Array.prototype.forEach.call(inp, function(item, i, arr) {
item.addEventListener('click', function() {
alert('fsdfs');
}, false);
});
不是这个问题的直接答案,而是底层实现的(更好)解决方案。
我推荐使用这个替代函数:
// forEach method, could be shipped as part of an Object Literal/Module
var forEach = function (array, callback, scope) {
for (var i = 0; i < array.length; i++) {
callback.call(scope, i, array[i]); // passes back stuff we need
}
};
// Usage:
// optionally change the scope as final parameter too, like ECMA5
var myNodeList = document.querySelectorAll('li');
forEach(myNodeList, function (index, value) {
console.log(index, value); // passes index + value back!
});
有一个非常好的和详细的博客 post(来自 Google 员工)here,解释了 [].forEach.call(NodeList)
-hack 以及为什么您应该避免使用它。
编辑:我知道答案最好包含任何外部参考的相关部分。但是,我不能说得更好 *而且*它是一个 github.io link,应该不会很快消失。
这会使用工作版本更新您的原始代码,它甚至是通用的。只需传递选择器字符串,它就会附加点击功能。
function setClickHandlers(selector)
{
var inp = document.querySelectorAll(selector);
Array.prototype.forEach.call(inp, function(item, i, arr) {
item.addEventListener('click', clickHandlerButton
, false);
});
}
function clickHandlerButton()
{
alert('fsdfs');
}
document.getElementById('start').addEventListener('click',function() {
var gg = '<input type="button" value="Button1" class="z1"><input type="button" value="Button2" class="z1">';
document.body.insertAdjacentHTML('beforeEnd', gg);
setClickHandlers('.z1');
});
要防止您的程序向每个按钮添加匿名函数,您可以在单击事件中引用一个函数。这可以节省一些内存 space 并使代码更新更容易。
然而 dfsq 有最优雅的解决方案,这只需要设置一个点击处理程序。当元素没有子元素时,这会很好地工作。
为了完整起见,这里有一个完整不同的方法:
// Objects could hold additional attributes to be set in addBtns();
// see http://fiddle.jshell.net/eyecatchup/e39wwzwu/2/show/light/ for details.
var btnMap = [{val: 'Button1'}, {val: 'Button2'}],
startBtn = document.getElementById('start');
function addBtns() {
for (i in btnMap) {
var _el = startBtn.cloneNode(!0, !1);
_el.removeAttribute('id'); // remove id property of source node!
_el.value = btnMap[i].val;
_el.setAttribute('onclick', "alert('fsdfs')");
_el.className = 'z1'; // optional!
startBtn && startBtn.parentNode.appendChild(_el);
}
}
(function(){
startBtn && startBtn.addEventListener('click', addBtns);
})();
*{margin:0;padding:10px;} .z1{margin-left:10px; font-weight:bold;}
<input type="button" value="Start" id="start">
HTML:
<input type="button" value="Start" id="start">
JavaScript:
var inp = document.querySelectorAll('.z1');
Array.prototype.forEach.call(inp, function(item, i, arr) {
item[i].addEventListener('click', function() {
alert('fsdfs');
}, false);
});
document.getElementById('start').addEventListener('click',function() {
var gg = '<input type="button" value="Button1" class="z1"><input type="button" value="Button2" class="z1">';
document.body.insertAdjacentHTML('beforeEnd', gg);
});
这个想法是当你点击插入正文中的 INPUT 时应该触发警报。
不会为新元素触发警报,因为您从未将事件绑定到它们。而是将点击事件委托给主体,它最终会在主体中冒泡:
document.body.addEventListener('click', function(e) {
if (e.target.className == 'z1') {
alert('fsdfs');
}
}, false);
document.getElementById('start').addEventListener('click',function() {
var gg = '<input type="button" value="Button1" class="z1"><input type="button" value="Button2" class="z1">';
document.body.insertAdjacentHTML('beforeEnd', gg);
});
<input type="button" value="Start" id="start">
请记住,在委托事件的情况下,您需要检查事件是否发生在正确的元素上。就像在演示中一样,您可以检查事件目标 class name.
您的 selector 将 select 与您显示的 HTML 没有任何关系,但是,如果您的 selector 正在工作,那么这是正确的代码
Array.prototype.forEach.call(inp, function(item, i, arr) {
item.addEventListener('click', function() {
alert('fsdfs');
}, false);
});
不是这个问题的直接答案,而是底层实现的(更好)解决方案。
我推荐使用这个替代函数:
// forEach method, could be shipped as part of an Object Literal/Module
var forEach = function (array, callback, scope) {
for (var i = 0; i < array.length; i++) {
callback.call(scope, i, array[i]); // passes back stuff we need
}
};
// Usage:
// optionally change the scope as final parameter too, like ECMA5
var myNodeList = document.querySelectorAll('li');
forEach(myNodeList, function (index, value) {
console.log(index, value); // passes index + value back!
});
有一个非常好的和详细的博客 post(来自 Google 员工)here,解释了 [].forEach.call(NodeList)
-hack 以及为什么您应该避免使用它。
编辑:我知道答案最好包含任何外部参考的相关部分。但是,我不能说得更好 *而且*它是一个 github.io link,应该不会很快消失。
这会使用工作版本更新您的原始代码,它甚至是通用的。只需传递选择器字符串,它就会附加点击功能。
function setClickHandlers(selector)
{
var inp = document.querySelectorAll(selector);
Array.prototype.forEach.call(inp, function(item, i, arr) {
item.addEventListener('click', clickHandlerButton
, false);
});
}
function clickHandlerButton()
{
alert('fsdfs');
}
document.getElementById('start').addEventListener('click',function() {
var gg = '<input type="button" value="Button1" class="z1"><input type="button" value="Button2" class="z1">';
document.body.insertAdjacentHTML('beforeEnd', gg);
setClickHandlers('.z1');
});
要防止您的程序向每个按钮添加匿名函数,您可以在单击事件中引用一个函数。这可以节省一些内存 space 并使代码更新更容易。
然而 dfsq 有最优雅的解决方案,这只需要设置一个点击处理程序。当元素没有子元素时,这会很好地工作。
为了完整起见,这里有一个完整不同的方法:
// Objects could hold additional attributes to be set in addBtns();
// see http://fiddle.jshell.net/eyecatchup/e39wwzwu/2/show/light/ for details.
var btnMap = [{val: 'Button1'}, {val: 'Button2'}],
startBtn = document.getElementById('start');
function addBtns() {
for (i in btnMap) {
var _el = startBtn.cloneNode(!0, !1);
_el.removeAttribute('id'); // remove id property of source node!
_el.value = btnMap[i].val;
_el.setAttribute('onclick', "alert('fsdfs')");
_el.className = 'z1'; // optional!
startBtn && startBtn.parentNode.appendChild(_el);
}
}
(function(){
startBtn && startBtn.addEventListener('click', addBtns);
})();
*{margin:0;padding:10px;} .z1{margin-left:10px; font-weight:bold;}
<input type="button" value="Start" id="start">