JS模块导入时出现addEventListener空指针错误求助
问题与解决方案
问题描述
我有script.js和au-script.js两个JS文件,计划从au-script.js向script.js导入函数与数组。但打开关联script.js的index.html页面时,控制台抛出错误:
TypeError: Cannot read properties of null (reading 'addEventListener') at au-script.js:7:12
原因是index.html中不存在au-script.js代码里尝试获取的DOM元素,导致调用addEventListener时出错。
相关代码
au-script.js
let userName = document.getElementById("name") let nameValue; let userNum; let newInfo = []; const getNameBtn = document.getElementById("getNameBtn"); getNameBtn.addEventListener("click", () => { randomNumber() getName() console.log(newInfo[newInfo.length - 1].name) }) function getName() { nameValue = userName.value; document.getElementById("showName").textContent = nameValue if (nameValue) { newInfo.push({ name:nameValue }, { user: userNum}) } else { alert("名前を入力してください") } } function randomNumber() { let getRandomNum = Math.floor(Math.random() * 20000) + 10000 userNum = getRandomNum } export {newInfo, getName, randomNumber}
script.js
import { newInfo, getName, randomNumber} from "./2nd-page/au-script.js"; const getNumber = document.getElementById("number"); const getValueBtn = document.getElementById("getValueBtn") let getValueNumber getValueBtn.addEventListener("click", () => { getValueNumber = getNumber.value findE() console.log(employees) addNewUser() }) let employees = [{ user: "20001", name:"レイン", workDays:"20" + "Days", }, { user: "20002", name:"アモルファスカーボン", workDays: "21" + "Days" }] function addNewUser() { employees.push(newInfo) } function findE() { const findUser = employees.find(u => u.user == getValueNumber) if (findUser) { document.getElementById("name").innerHTML = findUser.name document.getElementById("workDays").innerHTML = findUser.workDays } else { document.getElementById("name").innerHTML = "登録されていません" document.getElementById("workDays").innerHTML = "登録されていません" } console.log(findUser) }
index.html(关联script.js)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="style.css"> </head> <body> <h1>タイムカードシステム</h1> <div class="container"> <input type="number" name="number" id="number" inputmode="numeric" placeholder="作業員番号を入力してください"/> </div> <div class="btn-container"> <button id="getValueBtn">エンター</button> </div> <div class="userInfo"> 名前:<p id="name"></p> 出勤日数:<p id="workDays"></p> </div> <div class="pages-container"> <p></p> <a href="/2nd-page/adduser.html">"新し作業員を登録する"</a> </div> <script type="module" src="script.js" ></script> </body> </html>
adduser.html(关联au-script.js)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="/2nd-page/au-style.css"> </head> <body> <div class="text-container"> <h1>登録と削除システム</h1> <p>新し作業員を登録する</p> <input type="text" name="name" id="name" placeholder="名前を入力してください"/> <button id="getNameBtn">登録する</button> </div> <div class="userInfo"> 名前:<p id="showName"></p> </div> <script type="module" src="/2nd-page/au-script.js"></script> </body> </html>
解决方案
问题核心是:当script.js导入au-script.js时,au-script.js内所有代码都会执行,包括获取DOM元素和绑定事件的逻辑,但index.html中没有#getNameBtn、#showName这些元素,导致document.getElementById返回null,调用addEventListener触发报错。
修改后的au-script.js
// 纯逻辑部分,不依赖DOM,可安全导出 let userNum; let newInfo = []; function getName(userNameInput, showNameElement) { const nameValue = userNameInput.value; showNameElement.textContent = nameValue if (nameValue) { newInfo.push({ name: nameValue, user: userNum }); } else { alert("名前を入力してください") } } function randomNumber() { let getRandomNum = Math.floor(Math.random() * 20000) + 10000 userNum = getRandomNum } // DOM相关逻辑,仅在adduser.html页面执行 function initAddUserPage() { const userName = document.getElementById("name"); const getNameBtn = document.getElementById("getNameBtn"); const showName = document.getElementById("showName"); if (getNameBtn && userName && showName) { getNameBtn.addEventListener("click", () => { randomNumber(); getName(userName, showName); console.log(newInfo[newInfo.length - 1]?.name); }); } } // 判断当前页面是否为adduser.html,再初始化DOM逻辑 if (window.location.pathname.includes("adduser.html")) { initAddUserPage(); } export { newInfo, getName, randomNumber };
修改说明
- 重构
getName函数,改为接收DOM元素参数,不再直接在函数内获取DOM,避免依赖特定页面元素。 - 将DOM元素获取、事件绑定逻辑封装到
initAddUserPage函数中。 - 通过
window.location.pathname判断当前页面是否为adduser.html,仅在该页面执行DOM初始化逻辑,避免在index.html中触发错误代码。 - 修正
newInfo.push的错误:原写法会将两个对象分别推入数组,合并为单个对象{ name: nameValue, user: userNum },避免数组结构混乱。
修改后,script.js导入au-script.js时仅执行纯逻辑部分,不会触发DOM相关代码;adduser.html加载au-script.js时则会正常初始化DOM事件。
内容的提问来源于stack exchange,提问作者woopwoop
相关产品推荐
相关产品推荐

