我正在开发一个星级评级系统。我想在星星图像列表上设置事件侦听器,以便单击星星可以用实心或空白星星填充星星。问题是,当使用参数设置 getElementById 以将事件侦听器添加到列表项时,根据循环迭代正确设置了变量 (myId),但将相同的变量传递给运行 onclick 的函数会返回 (myId) 的最后一个值) 而不是循环迭代值。 我知道代码正在工作,就像我为传递的变量硬编码一个值一样,它的工作原理如下是代码:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Star Rating</title>
</head>
<body>
<ul>
<li class="myClass" id="liId113"><img src="images/starFade.png"></li>
<li class="myClass" id="liId213"><img src="images/starFade.png"></li>
<li class="myClass" id="liId313"><img src="images/starFade.png"></li>
<li class="myClass" id="liId413"><img src="images/starFade.png"></li>
<li class="myClass" id="liId513"><img src="images/starFade.png"></li>
</ul>
</body>
<script>
window.onload = setArray;
function setArray() {
let myArray = document.getElementsByClassName("myClass");
let l = myArray.length;
for(var i = 0;i < l;i++) {
myId = String(myArray[i].id);
document.getElementById(myId).addEventListener("click", function () {highlightStar(myId);});
//This adds event listeners to each <li> element using the correct myId but the myId of highlightStar is the last value of MyId
}
}
function highlightStar(myId) {
firstPart = myId.slice(0,4);
sequenceNo = myId.charAt(4);
group = myId.slice(-2);
if (sequenceNo == 5) {
document.getElementById(myId).innerHTML = "<img src='images/starFull.png'>";
document.getElementById(firstPart+4+group).innerHTML = "<img src='images/starFull.png'>";
document.getElementById(firstPart+3+group).innerHTML = "<img src='images/starFull.png'>";
document.getElementById(firstPart+2+group).innerHTML = "<img src='images/starFull.png'>";
document.getElementById(firstPart+1+group).innerHTML = "<img src='images/starFull.png'>";
}
else if (sequenceNo == 4) {
document.getElementById(myId).innerHTML = "<img src='images/starFull.png'>";
document.getElementById(firstPart+5+group).innerHTML = "<img src='images/starFade.png'>";
document.getElementById(firstPart+3+group).innerHTML = "<img src='images/starFull.png'>";
document.getElementById(firstPart+2+group).innerHTML = "<img src='images/starFull.png'>";
document.getElementById(firstPart+1+group).innerHTML = "<img src='images/starFull.png'>";
}
else if (sequenceNo == 3) {
document.getElementById(myId).innerHTML = "<img src='images/starFull.png'>";
document.getElementById(firstPart+5+group).innerHTML = "<img src='images/starFade.png'>";
document.getElementById(firstPart+4+group).innerHTML = "<img src='images/starFade.png'>";
document.getElementById(firstPart+2+group).innerHTML = "<img src='images/starFull.png'>";
document.getElementById(firstPart+1+group).innerHTML = "<img src='images/starFull.png'>";
}
else if (sequenceNo == 2) {
document.getElementById(myId).innerHTML = "<img src='images/starFull.png'>";
document.getElementById(firstPart+5+group).innerHTML = "<img src='images/starFade.png'>";
document.getElementById(firstPart+4+group).innerHTML = "<img src='images/starFade.png'>";
document.getElementById(firstPart+3+group).innerHTML = "<img src='images/starFade.png'>";
document.getElementById(firstPart+1+group).innerHTML = "<img src='images/starFull.png'>";
}
else if (sequenceNo == 1) {
document.getElementById(myId).innerHTML = "<img src='images/starFull.png'>";
document.getElementById(firstPart+5+group).innerHTML = "<img src='images/starFade.png'>";
document.getElementById(firstPart+4+group).innerHTML = "<img src='images/starFade.png'>";
document.getElementById(firstPart+3+group).innerHTML = "<img src='images/starFade.png'>";
document.getElementById(firstPart+2+group).innerHTML = "<img src='images/starFade.png'>";
}
}
</script>
</html>
您面临的问题涉及变量范围。目前,您的变量
myId
的范围不限于循环,因此每次迭代都会被覆盖,从而导致最后一个值被存储并在事件侦听器中使用。为了解决这个问题,您可以使用 JavaScript 闭包。这可以确保每个事件侦听器保留对其相关循环迭代值的访问:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Star Rating</title>
</head>
<body>
<ul>
<li class="myClass" id="li1"><img src="images/starFade.png" alt="star image"></li>
<li class="myClass" id="li2"><img src="images/starFade.png" alt="star image"></li>
<li class="myClass" id="li3"><img src="images/starFade.png" alt="star image"></li>
<li class="myClass" id="li4"><img src="images/starFade.png" alt="star image"></li>
<li class="myClass" id="li5"><img src="images/starFade.png" alt="star image"></li>
</ul>
</body>
<script>
window.onload = function setArray() {
let myArray = document.getElementsByClassName("myClass");
for(var i = 0; i < myArray.length; i++) {
let myId = myArray[i].id;
document.getElementById(myId).addEventListener("click", (function(myId) {
return function() {highlightStar(myId);};
})(myId));
}
}
function highlightStar(myId) {
let sequenceNo = parseInt(myId.replace('li',''));
let myArray = document.getElementsByClassName("myClass");
for(var i = 0; i < myArray.length; i++) {
let id = myArray[i].id;
let currentNo = parseInt(id.replace('li',''));
if (currentNo <= sequenceNo) {
document.getElementById(id).innerHTML = "<img src='images/starFull.png' alt='star image'>";
} else {
document.getElementById(id).innerHTML = "<img src='images/starFade.png' alt='star image'>";
}
}
}
</script>
</html>