我有一个如下所示的网站。 当一个文本被点击时,被点击的文本将得到一个名为 large 的类,并且文本大小将变为 25pt。要了解我如何分配事件和类 large,请查看 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>
答案 0 :(得分:2)
您的循环变量未显式声明,因此它获得了一个隐式 var
声明作为全局变量。
您在事件处理程序中使用循环变量会在 index
周围创建 a closure,因此当这些处理程序运行(稍后)时,它们访问该循环变量的最后一个值,因此仅访问最后一个元素受到影响。
使用 let
声明具有块作用域的循环变量来解决问题。
.getElementsByClassName()
和
使用 .querySelectorAll()
。.getElementsByClassName()
和 .querySelectorAll()
返回类似于数组的集合,因此它们中的任何一个都不是
需要 Array.from()
如果您要使用计数循环来
迭代它。for/in
循环不应用于枚举数组
Array 的所有属性,而不仅仅是索引。 for/in
should only be used on objects。.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>