eventListener和封闭的元素

时间:2017-12-17 19:24:15

标签: javascript html

有一段代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Events Examples</title>
    <style>
        ul {
            width: 200px;
            height: 200px;
            margin: 10px;
            background-color: #ccc;
            float: left;
        }

        .highlight {
            background-color: red;
        }
    </style>
</head>
<body>
<ul id="list">
    <li>First</li>
    <li>Second</li>
    <li>Third</li>
</ul>
<script>
    const ul = document.querySelector('#list');
    ul.addEventListener('mouseover', highlight);
    ul.addEventListener('mouseout', highlight);

    function highlight(event) {
        console.log(event.target);
        event.target.classList.toggle('highlight');
    }
</script>
</body>
</html>

启动时,它看起来像这样:

enter image description here

我对听众的期望。当我将鼠标移动到&#39; ul&#39;的灰色区域时,则highlight()函数应该起作用。好吧,它运作正常。我不明白的是:当我将鼠标移动过来时,我会立即理解。元素,然后highlight()再次出于未知原因。怎么修好? 我是JS的新手,我没有找到所描述问题的答案。

enter image description here enter image description here

3 个答案:

答案 0 :(得分:2)

事件总是冒泡,但如果您想要选择实际添加了侦听器的元素,请使用event.currentTarget代替event.target

function highlight(event) {
    console.log(event.currentTarget);
    event.currentTarget.classList.toggle('highlight');
}

有关事件冒泡的信息:What is event bubbling and capturing?

如果您想确保仅在您注册的元素上调用该事件,则可以检查target是否与currentTarget匹配。

答案 1 :(得分:2)

如果您只想突出显示整个区域,请改用"mouseenter""mouseleave",然后使用this来引用该元素。

然后没有事件冒泡问题需要处理。

const ul = document.querySelector('#list');
ul.addEventListener('mouseenter', highlight);
ul.addEventListener('mouseleave', highlight);

function highlight(event) {
  this.classList.toggle('highlight');
}
ul {
  width: 200px;
  height: 200px;
  margin: 10px;
  background-color: #ccc;
  float: left;
}

.highlight {
  background-color: red;
}
<ul id="list">
  <li>First</li>
  <li>Second</li>
  <li>Third</li>
</ul>

答案 2 :(得分:1)

如果你将一个元素包含在另一个元素中,那么&#34; inner&#34; element(在您的情况下,<li>将触发mouseover事件,这将&#34;冒泡&#34;直到您附加侦听器的元素。事件的target属性将是触发事件的内部元素,而不是附加侦听器的元素。

使用currentTarget代替目标,而不是目标,它指示您将侦听器附加到的元素。

更新正如@Terminus指出的那样,这可能导致事件的多次处理,因为鼠标悬停在li和ul上将触发由侦听器处理的鼠标悬停事件。如果目标 currentTarget

,那么解决方案就是只运行代码
if(event.target === event.currentTarget)
     event.currentTarget.classList.toggle('highlight');