通过JS for循环添加网格empty-div后,id为you的可移动div无法移动的原因排查
通过JS for循环添加网格empty-div后,id为you的可移动div无法移动的原因排查
嘿,我揪出问题的核心了!你遇到的这个“数据看起来正常但元素纹丝不动”的诡异情况,根源是**innerHTML +=这个操作悄悄销毁了页面上原本的you元素,而你的JS代码还在操作那个已经被扔掉的旧元素引用**。
具体拆解一下整个过程:
- 页面加载后,你先执行了
const you = document.getElementById("you");,这时候你拿到了页面上初始存在的那个you元素的引用,它存在JS的内存里。 - 然后你在
initiate函数里用gridContainer.innerHTML += '<div class="empty-div"></div>'添加空白div——这个写法的本质是:先把容器里现有的所有HTML(包括you和me的代码)读出来,拼接上新的div代码,然后把容器里的所有旧元素全部删除,再重新渲染拼接后的HTML内容。 - 这时候页面上虽然还能看到
id="you"的元素,但它是全新创建的,和你存在you变量里的那个旧元素已经完全不是同一个东西了! - 所以你点击按钮时,确实在修改旧元素的
gridRow/gridColumn值(console.log能看到变化),但这个旧元素早就不在页面上了,页面上的新you元素根本没被你的JS代码操作,自然看起来一动不动。
你手动写100个div时没问题,是因为你没有触发innerHTML的重新渲染流程,初始的you元素引用一直有效,修改它的样式能直接反映到页面上。
你可以自己验证这个结论:在initiate函数执行完之后,在控制台打印you === document.getElementById("you"),结果肯定是false——这就实锤了两个元素不是同一个。
按照你“不想换其他方案,只想修正现有问题”的要求,有两个贴合你需求的调整方向:
- 换一种不销毁原有元素的方式添加空白div:用
document.createElement创建元素,再用appendChild添加,这样不会触动容器里已有的you和me元素:
const initiate = () => { for (let i = 0; i < 98; i++) { const emptyDiv = document.createElement('div'); emptyDiv.className = 'empty-div'; gridContainer.appendChild(emptyDiv); } upBtn.addEventListener("click", moveUp); leftBtn.addEventListener("click", moveLeft); downBtn.addEventListener("click", moveDown); rightBtn.addEventListener("click", moveRight); }
- 如果坚持用
innerHTML,就在操作后重新获取元素引用:把获取you和me的代码移到innerHTML操作之后,确保拿到的是页面上最新的元素:
const gridContainer = document.getElementById("grid-container"); const upBtn = document.getElementById("up-btn"); const leftBtn = document.getElementById("left-btn"); const downBtn = document.getElementById("down-btn"); const rightBtn = document.getElementById("right-btn"); let youPosition = { x: 1, y: 1 } let mePosition = { x: 10, y: 10 }; // ... 保留moveUp等函数逻辑不变 const initiate = () => { for (let i = 0; i < 98; i++) { gridContainer.innerHTML += `<div class="empty-div"></div>`; } // 重新获取页面上最新的元素引用 const you = document.getElementById("you"); const me = document.getElementById("me"); // 绑定事件时确保操作的是新元素 upBtn.addEventListener("click", () => { if (youPosition.y > 1) { youPosition.y--; you.style.gridRow = youPosition.y; } console.log(youPosition); console.log(you.style.gridRow + " " + you.style.gridColumn); }); // 同理修改其他按钮的事件绑定,或者把moveUp等函数改成接收you参数 }
这样就能保证你的JS代码操作的是页面上实际存在的那个you元素,自然就能正常移动了。
备注:内容来源于stack exchange,提问作者NyctophobianDream
相关产品推荐
相关产品推荐

