先来说一下事情的经过:今天心血来潮,打开b站想跟着某个视频简单的敲个小demo,结果刚写完第一个页面的js就开始报错Cannot read property 'addEventListener' of null。代码如下
entry.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/entry.js"></script>
</head>
<body>
<input type="text" id="username" placeholder="请输入用户名">
<button id="enter">进入聊天室</button>
</body>
</html>
entry.js
;((doc, storage, location) => {
const oUsername = doc.querySelector("#username");
const oEnterBtn = doc.querySelector("#enter");
const init = () => {
bindEvent();
}
function bindEvent() {
oEnterBtn.addEventListener('click', handlerEnterBtnClick, false);
}
function handlerEnterBtnClick() {
const username = oUsername.value.trim();
if(username.length < 6) {
alert('用户名不得小于6位');
return;
}
storage.setItem('username', username);
location.href = 'index.html';
}
init();
})(document, localStorage, location);
然后打开浏览器,习惯性的打开控制台,看到了这个报错:
然后我就去entry.js中仔细的检查,看看我是不是哪块单词拼写出错,找了老半天也没有发现,这可给我难受坏了,然后我继续从头开始一个字一个字的看一遍,依然没有发现有什么错误,百思不得其解, 我突然发现entry.js是写了一个立即执行函数,会不会是在页面还没加载完的时候这个js就已经执行完了,所以会报错。根据我的猜想我试着改了改entry.js,然而依旧报错。然后我撤销修改去引入的位置进行改动
然后它居然好了,所以看来是因为在页面没有加载完成时,这段监听的js代码已经执行完毕,在执行这段代码时监听的DOM节点还没有创建,所以找不到监听元素,只能返回null。
解决方法就是 等待页面加载完成时,再执行js代码;在原生js中,将脚本放在底部。