Etch-A-Sketch画板DOM加载异常:appendChild报Null值错误求助
问题:appendChild执行时出现Null值,无法读取id为etch的元素
运行代码时第9行执行appendChild报错Null值,怀疑代码找不到id为etch的元素。之前在MDN playground里把JS和CSS写在HTML里能正常运行,但改用外部文件就出问题了,求帮助。
代码示例
HTML代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="script.js" defer></script> <link rel="stylesheet" href="style.css"> <title>Document</title> </head> <body> <div id="etch"></div> </body> </html>
JavaScript代码
let num = 16; let etch = document.getElementById("etch"); function board () { for(let i = 0; i < num; i++) { let row = document.createElement("div"); row.classList.add("row"); etch.appendChild(row); for(let j = 0; j < num; j++) { let column = document.createElement("div"); column.classList.add("column"); row.appendChild(column); } } } board();
CSS代码
*{ box-sizing: border-box; margin: 0; padding: 0; } #etch{ margin: 27px; display: flex; flex-direction: column; width: 500px; height: 500px; border: black 2px solid; } .column{ display: flex; flex-grow: 1; background-color: silver; } .row{ flex-grow: 1; border: white 1px solid; }
原因及解决办法
核心问题是DOM元素还未加载完成,JS就尝试获取它。虽然你给script标签加了defer,但脚本顶部的let etch = document.getElementById("etch");会在脚本执行时立即运行,若此时DOM还未完全解析,就会返回null。
解决方式一:把元素获取逻辑移到函数内部
修改JS代码,将获取etch元素的代码放到board()函数里,这样只有当函数执行时才会去查找DOM元素:
let num = 16; function board () { let etch = document.getElementById("etch"); // 移到函数内部 for(let i = 0; i < num; i++) { let row = document.createElement("div"); row.classList.add("row"); etch.appendChild(row); for(let j = 0; j < num; j++) { let column = document.createElement("div"); column.classList.add("column"); row.appendChild(column); } } } board();
解决方式二:监听DOM加载完成事件
如果不想移动变量,可以将board()的调用放在DOMContentLoaded事件回调中,确保DOM完全加载后再执行代码:
let num = 16; let etch = document.getElementById("etch"); function board () { for(let i = 0; i < num; i++) { let row = document.createElement("div"); row.classList.add("row"); etch.appendChild(row); for(let j = 0; j < num; j++) { let column = document.createElement("div"); column.classList.add("column"); row.appendChild(column); } } } // 等待DOM加载完成后执行board函数 document.addEventListener('DOMContentLoaded', board);
为什么MDN Playground里没问题?
在MDN Playground中,你是将JS代码直接写在HTML的<script>标签中(通常放在<body>末尾),此时浏览器已经解析完所有DOM元素,所以能正常获取到etch节点。而使用外部脚本时,若未处理好执行时机,就会出现元素未创建就被调用的情况。
内容的提问来源于stack exchange,提问作者Reginald86
相关产品推荐
相关产品推荐

