//这可行
for (var i = 0; i < 5; i++) {
var btn = document.createElement('button');
btn.appendChild(document.createTextNode('Button ' + i));
btn.addEventListener('click', (function(i) {
return function() {console.log(i)};
})(i));
document.body.appendChild(btn);
}
//这不起作用
for (var i = 0; i < 5; i++) {
var btn = document.createElement('button');
btn.appendChild(document.createTextNode('Button ' + i));
btn.addEventListener('click', (function(i) {
return console.log(i);
})(i));
document.body.appendChild(btn);
}
有人能告诉我为什么第二个例子不起作用?你为什么需要返回一个函数?
答案 0 :(得分:2)
因为您正在使用IIFE,我们可以用它的返回值替换它。所以第一个例子类似于
btn.addEventListener('click', function() {console.log(i)});
,第二个例子类似于
btn.addEventListener('click', console.log(i));
(i
的实际值与手头的问题无关)
addEventListener
期望将函数作为第二个参数传递,但第二个示例不传递函数。它传递console.log
的返回值,即undefined
。所以没有什么可以点击执行。
为什么eventlistener click需要返回函数才能工作
请注意,事件侦听器不会返回函数。在第一个示例中,function() {console.log(i)}
是事件处理程序。外部函数(function(i) { ... }(i))
只是生成事件处理程序的函数。
答案 1 :(得分:1)
所以从本质上讲,你订阅的是一个将在某个地方发生的事件(一旦你点击按钮)。
在第一个(工作)示例中,当您创建IIFE并且IIFE的结果是函数时,当事件发生时,会有一个回调函数(返回函数)被调用以生成所需的结果。
在第二个(非工作)示例中,您将创建一个立即执行的IIFE,以便您得到以下内容:
btn.addEventListener('click', undefined);
由于第二个参数不是函数(根据需要),一旦按下按钮并且回调被触发,就无需执行任何操作。
答案 2 :(得分:0)
因为第一个例子并没有真正返回一个函数。您的函数无处可以返回任何内容,因此无法返回任何内容。在你的第一个例子中,它返回一个函数,但该函数实际上只是调用console.log(i);
。如果你说console.log(i);
而不是return console.log(i);