事件的范围内部循环中的监听器

时间:2016-09-14 21:03:30

标签: javascript scope addeventlistener

eventListener如何在 forLoop 中工作?

代码适用于示例。

当我在任一段落上切换时,它会变得较低的不透明度并且有一个突破。 当我将鼠标悬停在任一段上时,它们会变成蓝色。

我想了解在浏览器加载页面后如何在for循环中实现 。我只是想了解浏览器如何解释这段代码。

var someTag = document.querySelectorAll("p")

for (var i = 0; i < someTag.length; i++) {


  someTag[i].addEventListener('mouseover', function() {
    this.classList.add("someClass");
  });
  someTag[i].addEventListener('mouseout', function() {
    this.classList.remove("someClass");
  });

  someTag[i].addEventListener('click', function() {
    this.classList.toggle("done");
  })


}
.done {
  text-decoration: line-through;
  opacity: 0.5;
}

.someClass {
  color: blue;
}
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
  in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
  in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

2 个答案:

答案 0 :(得分:0)

当您向元素添加事件侦听器时,该元素将永久更改(除非您稍后使用removeEventListener()将其删除)。只要在元素上触发事件,浏览器就会自动调用侦听器函数。您只需要添加一次侦听器,然后它将对事件的所有未来事件做出反应。

您需要知道的另一件事是,在侦听器函数中,this将是对触发事件的元素的引用。这就是您的功能如何更改您单击或悬停的段落的类别。

答案 1 :(得分:0)

首先关闭此代码只是因为您要将值附加到此代码,在这种情况下,这是您要悬停的值。 当您将鼠标悬停在p标记上时代码才有效,因为此代码设置为您正在悬停的当前 p 标记。它与i的价值无关。

请参阅下面的小提琴。

https://jsfiddle.net/vatsalpande/w1ao28d2/

javascript中的变量是函数作用域,这意味着即使你不在循环中,i的值仍然可用。因此,当您将鼠标悬停在p标记上时,i的值为2,这是未定义的。请检查小提琴控制台日志。

var someTag = document.querySelectorAll("p")

//ES5
for (var i = 0; i < someTag.length; i++) {


  someTag[i].addEventListener('mouseover', function() {
console.log(this);
if(i == 0){
    this.classList.add("someClass0");
}else if(i == 1){
    this.classList.add("someClass1");
}else{
    console.groupCollapsed(' See Information regarding variable values for mouseover');
    console.log(someTag[i]);
  console.log(i);
    console.log(this);
  console.groupEnd();
    this.classList.add("someClass2");
}

});
someTag[i].addEventListener('mouseout', function() {
 if(i == 0){
    this.classList.remove("someClass0");
}else if(i == 1){
     this.classList.remove("someClass1");
}else{
  console.groupCollapsed(' See Information regarding variable values for mouseout');
    console.log(someTag[i]);
    console.log(i);
    console.log(this);
    console.groupEnd();

    this.classList.remove("someClass2");
 }

});

  someTag[i].addEventListener('click', function() {
  console.groupCollapsed(' See Information regarding variable values for click');
    console.log(someTag[i]);
  console.log(i);
    console.log(this);
  console.groupEnd();
this.classList.toggle("done");
})
}

然而,对于ES6,我们有let关键字,它为我们提供了块范围,你可以在事件处理程序中使用变量i,而不必担心管理变量状态。

https://jsfiddle.net/vatsalpande/53x2LdyL/

addEventListener()方法在它调用的EventTarget(元素)上注册指定的侦听器。因此每当任何事件被解雇时都会调用它。