JavaScript设置DOM背景色,调用清空方法后后续样式更新失效如何解决?
问题原因
1. 同步连续调用时看不到中间状态
你将三次方法调用写在JS里同步执行时,浏览器的渲染机制会批量合并所有样式修改操作,不会每次修改都立刻重绘页面。displayScreen.writesquare(array)→displayScreen.clearScreen()→displayScreen.writesquare(array)会同步依次执行,全部执行完成后才会触发一次页面渲染,中间的样式变更过程你感知不到,只会渲染最后一次调用的结果。如果实际执行顺序最后一步是clearScreen,就会看起来writesquare没有生效。
2. 控制台手动调用时array变量未全局暴露
如果你是在Chrome控制台手动依次调用方法时出现问题,大概率是你定义的const array没有挂载到全局作用域,控制台调用displayScreen.writesquare(array)时会抛出array is not defined错误,函数没有正常执行,自然不会修改样式。
3. DOM未加载完成就执行JS
如果你的JS代码放在<head>标签内,没有等待DOM加载完成就执行,document.querySelectorAll(".block")会拿到空的NodeList,所有样式修改都不会生效。
解决方法
- 如果需要看到中间的状态变化,把后续调用放在异步队列里,给浏览器留出重绘时间:
const array = ["x","o","x","o","x","o","x","o","x"]; displayScreen.writesquare(array); // 1秒后清屏 setTimeout(() => { displayScreen.clearScreen(); // 清屏1秒后重新设置颜色 setTimeout(() => { displayScreen.writesquare(array); }, 1000); }, 1000);
- 如果要在控制台调用,把
array变量挂载到全局window对象上:
window.array = ["x","o","x","o","x","o","x","o","x"];
之后在控制台调用displayScreen.writesquare(array)即可正常执行。
3. 把JS代码放在<body>标签末尾,或者等待DOMContentLoaded事件触发后再执行,确保能正确获取到所有.block元素:
document.addEventListener('DOMContentLoaded', () => { const array = ["x","o","x","o","x","o","x","o","x"]; displayScreen.writesquare(array); });
代码优化建议
forEach本身自带索引参数,不需要额外定义计数变量,避免手动维护计数出错:
const writesquare = (array) => { const blocks = document.querySelectorAll(".block"); blocks.forEach((element, index) => { element.style.backgroundColor = array[index] === "x" ? "red" : "blue"; }); };
内容的提问来源于stack exchange,提问作者Willem. R. Nieuwenhuis

