Node.js webserver站点按钮绑定addEventListener报null类型错误求助
问题根本原因
你的代码出错是因为JS代码执行顺序优先于DOM元素渲染:
你把包含getElementById("button1")的script标签放在了所有HTML元素的最顶部,浏览器加载页面时会从上到下逐行解析,执行到获取button1的代码时,id为button1的input元素还没有被渲染到页面中,document.getElementById("button1")返回值为null,自然无法调用addEventListener方法抛出报错。
至于绑定在document上的点击事件可以正常运行,是因为document对象在页面初始解析时就存在,点击事件触发时页面所有DOM已经加载完成,所以能正常找到demo元素修改内容。JS Fiddle上运行正常是因为平台默认会把你写的JS代码放在页面DOM加载完成后再执行,所以不会触发这个问题。
解决方法
你可以任选以下任意一种方案修复:
方案1:移动script标签位置
把所有script标签移动到</html>之前,也就是所有DOM元素的后面,修改后的index.html结构如下:
<!DOCTYPE html> <html> <style> table, th, td { border: 1px solid black; border-collapse: collapse; } th, td { padding: 5px; text-align: left; } </style> </head> <div> <input id="button1" type="button" value="Add"> </div> <br> <div class="custom-select" style="width:200px;"> <select> <option value="0">Select operation:</option> <option value="1">RUT240</option> <option value="2">FMB920</option> </select> </div> <br> <table id="t1"> <caption>Operation table</caption> <thead> <tr> <th>Operation code</th> <th>To Do</th> <th>Done</th> <th>Left</th> </tr> </thead> <tbody> <tr> <td>RUT240</td> <td>1000</td> <td>50</td> <td></td> </tr> <tr> <td>FMB920</td> <td>555</td> <td>50</td> <td id ="number1"></td> </tr> </tbody> </table> <p id="demo"></p> <!-- 将script标签移到所有DOM元素之后 --> <script src="/socket.io/socket.io.js"></script> <script> var socket = io.connect('/'); socket.on('stats', function(data) { console.log('Connected clients:', data.numClients); }); document.addEventListener('click', function(){ document.getElementById("demo").innerHTML = "Hello World!"; }); var button = document.getElementById("button1"); button.addEventListener("click", function(event){ document.getElementById('number1').textContent = 50; }); </script> </html>
方案2:把DOM操作代码包裹在DOMContentLoaded事件中
不需要修改script标签位置,把需要操作DOM的代码放到DOM加载完成的回调里即可:
document.addEventListener('DOMContentLoaded', function() { // 所有需要操作DOM的代码都放在这里面 var button = document.getElementById("button1"); button.addEventListener("click", function(event){ document.getElementById('number1').textContent = 50; }); });
方案3:给script标签添加defer属性
在原有script标签上添加defer属性,告诉浏览器等页面DOM加载完成后再执行这段JS代码:
<script src="/socket.io/socket.io.js" defer></script> <script defer> // 你原来的JS代码保持不变即可 </script>
内容的提问来源于stack exchange,提问作者Lukas Petrikas
相关产品推荐
相关产品推荐

