代码如下:
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);
});
}
}
日志#1和#2的工作方式完全符合预期,因此在进入事件监听器之前对象很好,但是日志#3打印出来:undefined
。
据我所知,当我转到页面并将鼠标悬停在eventListener目标上时,不再定义bundle [k],因为循环已经完成,但我该如何解决?该目标取决于相同的循环
答案 0 :(得分:0)
for
循环弄乱了Closure,因为它将相同的变量(k
)传递给所有addClass
次调用。因此,当调用addClass
时,它会查找k
的最新值(它将等于数组.length
的长度,因此未定义索引)。发生这种情况是因为for
的{{3}}在退出之前保持不变。因此,请使用forEach
围绕每个元素的不同范围(回调范围),从而解决您的问题。像这样:
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);
});
});
});