[英]Add eventListener inside a loop and create a listener function that depends on the loop but still works after loop finishes
Code as follows: 代码如下:
var classToAdd = 'myClass';
var addClass = function(el, cn) {
if (el.classList.contains(cn)) {
return;
} else {
el.classList.add(cn);
}
};
var bundles = [
{
selectedActivators: [`array containing 2 DOM objects`],
target: `DOM object`
},
{
selectedActivators: [`array containing 2 DOM objects`],
target: `DOM object`
},
{
selectedActivators: [`array containing 2 DOM objects`],
target: `DOM object`
}
];
for (var k=0; k<bundles.length; k++) {
for (var l=0; l<bundles[k].selectedActivators.length; l++) {
console.log(bundles[k].selectedActivators[l]); // log #1
console.log(bundles[k].target); // log #2
bundles[k].selectedActivators[l].addEventListener('mouseover', function() {
console.log(bundles[k]); // log #3
addClass(bundles[k].target, classToAdd);
});
bundles[k].selectedActivators[l].addEventListener('mouseout', function() {
removeClass(bundles[k].target, classToAdd);
});
}
}
Logs #1 and #2 work exactly as expected so the objects are fine before they go into the event listener, but log #3 prints: undefined
. 日志#1和#2完全按预期工作,因此对象在进入事件侦听器之前可以正常运行,但日志#3显示: undefined
。
I understand that bundles[k] is not defined anymore when I go to the page and hover over the eventListener target because the loop has already finished, but how do I solve this? 我知道当我转到页面并将鼠标悬停在eventListener目标上时,不再定义bundles [k],因为循环已经完成了,但是我该如何解决呢? That target depends on the same loop 该目标取决于同一循环
The for
loop is messing up the Closure because it passes the same variable ( k
) to all the addClass
calls. for
循环使Closure混乱不堪,因为它将相同的变量( k
)传递给所有addClass
调用。 So when a addClass
is invoked, it's look for the up-to-date value of k
(which will be equal to the length of the array .length
thus undefined index). 因此,当调用addClass
时,它会查找k
的最新值(该值等于数组.length
的长度,因此未定义索引)。 That happens because the Scope of for
remains the same until it is exited. 发生这种情况是因为for
的作用域在退出之前一直保持不变。 So instead use forEach
which surrounds each element by a different scope (scope of the callback) thus solving your problem. 因此,请改用forEach
,它用不同的范围(回调范围)将每个元素包围起来,从而解决了您的问题。 Like this: 像这样:
bundles.forEach(function(bundlesK) {
bundlesK.selectedActivators.forEach(function(selActiv) {
selActiv.addEventListener('mouseover', function() {
addClass(bundlesK.target, classToAdd);
});
selActiv.addEventListener('mouseout', function() {
removeClass(bundlesK.target, classToAdd);
});
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.