为什么类"large"只添加到数组的最后一个元素中?



我有一个网站,看起来像下面。当文本被点击时,被点击的文本将获得一个名为large的类,并且文本大小将更改为25pt。要查看我如何分配事件和类大,请查看js代码。我遇到的问题是当文本"我喜欢游泳"时点击大类被添加到文本"我喜欢篮球"。为什么会发生这种情况?有人能帮我解决这个问题吗?

const arraySportsText = Array.from(document.getElementsByClassName('sportsText'));
for (index in arraySportsText) {
arraySportsText[index].addEventListener("click", () => arraySportsText[index].classList.add('large'))
}
body {
font-size: 15pt;
}
.large {
font-size: 25pt;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="styles/style.css">
</head>
<body>
<h1>Sports</h1>

<p class="sportsText">I like swimming</p>
<p class="sportsText">I like basketball</p>
<script src="scripts/hobby.js"></script>
</body>
</html>

你的循环变量没有显式声明,所以它得到一个隐式的var声明作为一个全局变量。

在事件处理程序中使用循环变量创建了围绕index的闭包,因此当这些处理程序运行(稍后)时,它们访问该循环变量的最后一个值,因此只有最后一个元素受到影响。

使用let声明你的循环变量块作用域来解决这个问题。

  • 另外,不要使用.getElementsByClassName()和代替使用.querySelectorAll().
  • .getElementsByClassName().querySelectorAll()返回类数组的集合,所以两者都不是如果要使用计数循环,则需要Array.from()迭代。
  • 并且,for/in循环不应该在数组上使用,因为它们枚举数组的所有属性,而不仅仅是索引。for/in应该只在对象上使用
  • 最后,.querySelectorAll()返回的集合可以是循环使用Array.prototype.forEach()方法,删除需要计数循环。

所以,修改后的代码应该是:

// Looping over the collection returned from .querySelectorAll()
// eliminates the need for a counting loop, which also removes
// the need to use that index in the event handler, which in turn,
// eliminates the closure problem you had in the first place.
document.querySelectorAll('.sportsText').forEach(function(element){
element.addEventListener("click", () => element.classList.add('large'))
});
body   { font-size: 15pt; }
.large { font-size: 25pt; }
<h1>Sports</h1>
<p class="sportsText">I like swimming</p>
<p class="sportsText">I like basketball</p>

最新更新