Hitori拼图mousedown匿名函数异常求助,已困扰一天
Hey there, I see you've been stuck on this for a day—let's get that puzzle grid working right! The core problem here is a super common closure trap caused by using var in your loop. Let's break it down and fix it step by step.
What's Going Wrong?
When you use var i in your for loop, i is scoped to the entire setupPuzzle function, not each iteration of the loop. By the time any of your mousedown events fire, the loop has already finished running, and i equals allCells.length—so allCells[i] becomes undefined, which breaks your style modification logic.
Simple Fix 1: Use let Instead of var
let creates block-scoped variables, meaning each loop iteration gets its own copy of i. This way, every mousedown handler references the correct index for the cell it's attached to:
function setupPuzzle() { // Use const to avoid global variable pollution (unless you need allCells globally) const allCells = document.querySelectorAll("table#hitoriGrid td"); // Replace var with let for block scoping for (let i = 0; i < allCells.length; i++) { allCells[i].style.backgroundColor = "white"; allCells[i].style.color = "black"; allCells[i].style.borderRadius = "0"; allCells[i].addEventListener("mousedown", function(evt) { if (evt.shiftKey) { allCells[i].style.backgroundColor = "white"; allCells[i].style.color = "black"; } else { // Example: Toggle to black background with white text for normal clicks allCells[i].style.backgroundColor = "black"; allCells[i].style.color = "white"; } }); } }
Even Cleaner Fix 2: Use forEach to Iterate
Instead of dealing with indexes at all, you can use forEach to loop through each cell directly. This eliminates the closure issue entirely by giving you direct access to each cell element in the callback:
function setupPuzzle() { const allCells = document.querySelectorAll("table#hitoriGrid td"); allCells.forEach(cell => { // Initialize cell styles cell.style.backgroundColor = "white"; cell.style.color = "black"; cell.style.borderRadius = "0"; cell.addEventListener("mousedown", function(evt) { if (evt.shiftKey) { cell.style.backgroundColor = "white"; cell.style.color = "black"; } else { cell.style.backgroundColor = "black"; cell.style.color = "white"; } }); }); }
Bonus Tip: Avoid Global Variables
Notice I changed allCells to a const—this keeps it scoped to the setupPuzzle function instead of polluting the global namespace, which is a best practice unless you specifically need to access this variable elsewhere in your code.
内容的提问来源于stack exchange,提问作者Martin Evtimov

