JavaScript中使用setAttribute传递索引参数至splatImg函数的问题
Let's break down the problems in your code and fix them one by one:
1. The onclick Event Isn't Using the Correct Index
The main issue here is that when you set onclick="splatImg(i)", the i in the string refers to the global variable i, not the current value of i during the loop iteration. By the time you click an image, the loop has finished, and i is 4 (since the loop runs for i < 4), which isn't a valid id for your images.
Fixing the createImg Function
We need to ensure each image's click handler uses the actual index value from the loop. There are two solid ways to do this:
Option 1: String Interpolation (Quick Fix)
Instead of passing i as a variable, insert the current value of i directly into the onclick string:
function createImg() { for (let i = 0; i < 4; i++) { const img = document.createElement("img"); img.setAttribute("id", i); img.setAttribute("onclick", `splatImg(${i})`); // Interpolate the current i value img.src = "images/bugImage.jpg"; document.getElementById("div1").appendChild(img); } }
Note: We removed the unnecessary initial img = document.createElement("img") line (you were treating this element as an array, which is incorrect) and used let for i to avoid global scope leaks.
Option 2: Event Listeners (Better Practice)
Using addEventListener avoids string evaluation and closure problems entirely. We capture the current i value with a block-scoped variable:
function createImg() { for (let i = 0; i < 4; i++) { const img = document.createElement("img"); img.id = i; img.src = "images/bugImage.jpg"; // Attach click listener with the current i img.addEventListener("click", () => splatImg(i)); document.getElementById("div1").appendChild(img); } }
This approach is cleaner and less error-prone than inline onclick attributes.
2. The splatImg Function Resets State Every Time
Right now, BUGS_CONDITION and BUGS are reinitialized every time you call splatImg, which means:
- The condition array resets to all
trueon every click - You're always removing the first element from
BUGS, not the one you clicked
Fixing the splatImg Function
Move the state variables outside the function so they persist between clicks, and update the logic to target the specific bug you clicked:
// Persist state outside the function so it doesn't reset const BUGS_CONDITION = [true, true, true, true]; const BUGS = ["bug1", "bug2", "bug3", "bug4"]; function splatImg(id) { // Convert id to a number (since it's passed as a string from the onclick attribute) const index = Number(id); // Only splat if the bug is still active if (BUGS_CONDITION[index]) { document.getElementById(id).src = "images/bugSplat.jpg"; // Remove the specific bug from the BUGS array BUGS.splice(index, 1); BUGS_CONDITION[index] = false; console.log(BUGS); } }
This way, each click targets the exact bug you clicked, and the state stays consistent between clicks.
Full Working Code
Here's the combined fixed code:
HTML:
<div id="div1"></div>
JavaScript:
const BUGS_CONDITION = [true, true, true, true]; const BUGS = ["bug1", "bug2", "bug3", "bug4"]; function createImg() { for (let i = 0; i < 4; i++) { const img = document.createElement("img"); img.id = i; img.src = "images/bugImage.jpg"; img.addEventListener("click", () => splatImg(i)); document.getElementById("div1").appendChild(img); } } function splatImg(id) { const index = Number(id); if (BUGS_CONDITION[index]) { document.getElementById(id).src = "images/bugSplat.jpg"; BUGS.splice(index, 1); BUGS_CONDITION[index] = false; console.log(BUGS); } } // Don't forget to call createImg to generate the images! createImg();
Now when you click each bug image, the splatImg function will receive the correct index (0-3), and the bug will be marked as splatted permanently until you reload the page.
内容的提问来源于stack exchange,提问作者Robert L

