我正在研究下面的代码片段。没有 setTimeOut(),它的工作完美,并在 loaded(id) 函数中向我显示 id。但是使用 setTimeOut() 这不能正常工作。
var menuLink = document.getElementsByClassName("li_common_class");
for(var i = 0; i < 5; i++ ) {
var childElement = menuLink[i];
childElement.addEventListener('click',setTimeout(function(){
loaded(childElement.id);
},100), true);
}
function loaded(id){
alert(id);
}
传递函数
您应该分配一个事件处理程序,但您要立即调用setTimeout
。
将函数传递给.addEventListener()
,并使用const
声明变量。
var menuLink = document.getElementsByClassName("li_common_class");
for (var i = 0; i < 5; i++) {
const childElement = menuLink[i];
childElement.addEventListener('click', function() {
setTimeout(function() {
loaded(childElement.id);
}, 100)
}, true);
}
function loaded(id) {
alert(id);
}
所以现在将函数作为第二个参数传递给.addEventListener
.该函数被分配为子元素的事件处理程序。我还使用const
声明了childElement
,否则您将始终获得分配给该变量的最后一个值,而不是每个循环迭代的相应值。
无需闭包参考
但是,这仍然不理想。您真的根本不需要childElement
,因为您已经在处理程序中引用了该元素。
var menuLink = document.getElementsByClassName("li_common_class");
for (var i = 0; i < 5; i++) {
menuLink[i].addEventListener('click', function(event) {
var targ = event.currentTarget
setTimeout(function() {
loaded(targ.id);
}, 100)
}, true);
}
function loaded(id) {
alert(id);
}
现在看到我向处理程序函数添加了一个event
参数。这使您可以获取处理程序绑定到的元素。
我们本可以使用this
而不是event.currentTarget
,但我们实际上在setTimeout
回调中丢失了该值。如果我们将箭头函数传递给setTimeout
,那么事件处理程序的this
就可以访问。
重用函数
但是,由于不再需要将函数与循环的每次迭代相关联,因此我们实际上可以将函数移动到循环之外,以便重用它。
var menuLink = document.getElementsByClassName("li_common_class");
for (var i = 0; i < menuLink.length; i++) {
menuLink[i].addEventListener('click', handler, true);
}
function handler(event) {
var targ = event.currentTarget
setTimeout(function() {
loaded(targ.id);
}, 100)
}
function loaded(id) {
alert(id);
}
<ul>
<li class="li_common_class" id="foo">CLICK ME</li>
<li class="li_common_class" id="bar">CLICK ME</li>
<li class="li_common_class" id="baz">CLICK ME</li>
</ul>
ES6
如果我们要使用 ES6,可以大大缩短相同的代码:
const menuLinkOnClick = event => setTimeout(() => alert(event.target.id), 100),
menuLinks = document.getElementsByClassName("li_common_class");
for (let menuLink of menuLinks) {
menuLink.addEventListener('click', menuLinkOnClick);
}
试试这个:
var menuLink = document.getElementsByClassName("li_common_class");
for (var i = 0; i < 5; i++) {
var childElement = menuLink[i];
(function (ce) {
ce.addEventListener('click', function () {
setTimeout(function () {
loaded(ce.id);
}, 100);
}, true);
})(childElement);
}
function loaded(id) {
alert(id);
}
试试这个:
var menuLink = document.getElementsByClassName("li_common_class");
for(i = 0; i < 5; i++) {
var childElement = menuLink[i];
childElement.addEventListener('click', function(){setTimeout(function(){loaded(childElement.id)},100)}, true);
}
function loaded(id){
alert(id);
}
你在 addEventListener() 中有一个函数 (setTimeout),但它没有放在 " 或 function(){} 中。您需要它在其中之一中,除非您希望它通过放置不带引号的 functionName 或 () 来调用没有参数的函数。
希望这有效。