简体   繁体   English

在循环内添加eventListener并创建一个依赖于循环的侦听器函数,但在循环完成后仍可使用

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM