You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 21:47:46