鼠标悬停的 addEventListener 在函数内有效,但在函数外无效

addEventListener for mouseover works within a function but not outside the function

我正在制作蚀刻草图,我正在尝试使用 'mouseover' 的 addEventListener 事件添加一个 CSS class,其中正方形的背景是鼠标悬停在上方会变黑。我有一个创建单个框的函数,如果我将事件侦听器放在这个函数中,它就可以工作,但是如果我尝试在函数外部执行它,它就不起作用

函数框创建一个框(将使用 addMultipleBox 函数重复)并添加鼠标悬停事件。在这种情况下,鼠标悬停可以正常工作

function box() {
    let square = document.createElement('div')
    square.setAttribute('class', 'box')
    container.appendChild(square)

    square.addEventListener('mouseover', () => {
        square.classList.add('blackPen')
    })
}

//creates the etch a sketch board with multiple 'boxes'
function addMultipleBoxes() {
    for(let i = 0; i < 256; i++) {
        box()
    }
}

现在,如果我尝试在函数外部获取 'box' 的 class 并向其添加事件侦听器,则不会发生任何事情。我确实在底部有这段代码,所以我并不是在创建 div 之前尝试获取它们。

我希望能够在外面抓住它,这样我就可以创建另一个功能,在鼠标单击时我删除了 'blackPen' 的 class,这将删除黑色的背景颜色广场,基本上把木板擦干净了。这就是我所拥有的

let boxx = document.querySelector('.box')

console.log(boxx)

boxx.addEventListener('mouseover', () => {
    boxx.classList.add('blackPen')
})

当我 console.log 'Boxx' 我得到 <div class="box"></div>。如果我在方框函数中 console.log 上面的“方形”,我会得到与 Boxx 相同的结果。

任何见解将不胜感激!

box() 函数根据需要将 class 添加到每个元素。

使用 querySelector 对元素的引用仅包含一个元素 - 文档中具有指定选择器的第一个元素。参见 https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector

这个片段用四个 div 来说明这个想法,都是一样的 class。

let boxx = document.querySelector('.box')


boxx.addEventListener('mouseover', () => {
    boxx.classList.add('blackPen')
})
.box {
  display: inline-block;
  width: 70px;
  aspect-ratio: 1;
  background: yellow;
  border: 1px solid red;
}

.blackPen {
  background: black;
}
<p><b>mouseover applied to element got by querySelector</b></p>
<p>(move mouse over divs)</d>

<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>

<p>querySelector, returns the <em>first</em> Element within the document that matches the specified selector</p>

可以使用 querySelectorAll() 来引用具有给定 class 的所有元素,其中 returns 是一个包含对给定选择器的所有元素的引用的活动节点列表。参见:https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll

完成引用后,您仍然需要遍历它们以添加所需的事件侦听器。节点列表和 html 集合是 array-like 结构,可以有 individual 成员和索引 [0],[1],等等。

此代码段说明了向使用 querySelectorAll:

形成的节点列表中的每个 div 添加一个新的 class

let boxx = document.querySelectorAll('.box')



for (let i=0; i<boxx.length; i++) {

boxx[i].addEventListener('mouseover', () => {
    boxx[i].classList.add('blackPen');
    boxx[i].classList.remove('cancel');
});

boxx[i].addEventListener('click', () => {
    boxx[i].classList.add('cancel')
});

} // next i boxx element;
.box {
  display: inline-block;
  width: 70px;
  aspect-ratio: 1;
  background: yellow;
  border: 1px solid red;
}

.blackPen {
  background: black;
}

.cancel {
  background: yellow;
}
<p><b>mouseover applied to all elements got by querySelectorAll</b><br>(move mouse over divs)</d>

<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>

<p>A click event was also added to all elements, to replace the class added by the mouseover event<br>click boxes to see the effect</p>

请注意,节点集合只需创建一次即可用于任何进一步的操作。在代码片段中,鼠标悬停事件添加了一个 class 以使背景变黑,而点击事件取消了它。