向#boundary添加同级div后,无法修改#box子div样式问题排查
问题分析与解决方案:无法修改#box样式的原因
嘿,我来帮你拆解下这个问题!你遇到的情况其实是DOM操作里一个很常见的坑——innerHTML +=的行为会毁掉你之前获取的DOM节点引用。
先看下你的简化代码:
let box = document.getElementById("box"); let boundary = document.getElementById("boundary") //添加此行后,我的代码无法将#box样式改为蓝色 boundary.innerHTML += "<div>A</div>" document.addEventListener("keydown", function(event) { if (event.key == "ArrowDown") { box.style.backgroundColor = "blue"; } });
问题根源
当你执行boundary.innerHTML += "<div>A</div>"时,浏览器会做这些事:
- 把
boundary原有的所有内容和新的<div>A</div>拼接成新的HTML字符串 - 销毁
boundary原来包含的所有DOM节点(包括你之前获取的#box节点) - 重新解析新的HTML字符串,生成全新的DOM节点插入到
boundary中
这就导致你之前存在box变量里的引用,指向的是已经被销毁的旧DOM节点,后续修改这个旧节点的样式,自然不会在页面上生效。
三种解决方案
方案一:重新获取#box的引用
在修改innerHTML之后,重新获取一次#box的DOM节点,这样拿到的就是新渲染后的有效节点:
let box = document.getElementById("box"); let boundary = document.getElementById("boundary") boundary.innerHTML += "<div>A</div>" // 重新获取box引用,指向新的DOM节点 box = document.getElementById("box"); document.addEventListener("keydown", function(event) { if (event.key == "ArrowDown") { box.style.backgroundColor = "blue"; } });
方案二:用appendChild替代innerHTML +=
这种方式不会销毁原有子元素,只是在boundary末尾添加新元素,之前的box引用依然有效:
let box = document.getElementById("box"); let boundary = document.getElementById("boundary") // 创建新div并添加,不影响原有节点 const newDiv = document.createElement("div"); newDiv.textContent = "A"; boundary.appendChild(newDiv); document.addEventListener("keydown", function(event) { if (event.key == "ArrowDown") { box.style.backgroundColor = "blue"; } });
方案三:在事件回调中实时获取#box
每次触发按键事件时再去获取#box节点,这样不管DOM怎么更新,拿到的都是当前最新的节点:
let boundary = document.getElementById("boundary") boundary.innerHTML += "<div>A</div>" document.addEventListener("keydown", function(event) { if (event.key == "ArrowDown") { // 每次触发事件时都获取最新的box节点 const box = document.getElementById("box"); box.style.backgroundColor = "blue"; } });
内容的提问来源于stack exchange,提问作者kojow7
相关产品推荐
相关产品推荐

