提交表单触发TypeError:无法读取null的addEventListener属性求助
解决方案:跳转后操作DOM报错的问题处理
问题根源
你遇到的Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')错误,核心原因是跳转后原页面的JS上下文会被销毁,你无法在原页面的代码里直接操作新页面(results.html)的DOM元素。当你用window.location.assign跳转时,原页面的代码停止执行,而新页面的DOM还未加载完成,此时尝试获取#search-results自然会得到null。
而用document.createElement创建页面时,所有操作都在当前页面的上下文里,DOM元素已经存在,所以不会报错。
可行方案
方案1:通过URL参数传递查询条件,在results.html中独立处理渲染
这种方式最通用,适合小量查询参数的场景:
原页面(表单所在页面)的提交逻辑:
阻止表单默认跳转,收集查询参数后拼接到跳转URL中:// 给表单绑定提交事件,替换成你的表单选择器 document.querySelector('#your-form-id').addEventListener('submit', function(e) { e.preventDefault(); // 阻止默认提交跳转 // 收集表单中的查询值,替换成你的字段名 const searchQuery = new FormData(this).get('search-input-name'); // 编码参数后跳转 window.location.assign(`results.html?q=${encodeURIComponent(searchQuery)}`); });results.html中的渲染逻辑:
等待DOM加载完成后,读取URL参数,查询localStorage并渲染卡片:// 等待DOM完全加载后执行 document.addEventListener('DOMContentLoaded', function() { // 获取目标容器,确保元素存在 const searchResultsContainer = document.getElementById('search-results'); if (!searchResultsContainer) { console.error('未找到#search-results容器'); return; } // 读取URL中的查询参数 const urlParams = new URLSearchParams(window.location.search); const query = urlParams.get('q'); if (!query) return; // 从localStorage获取数据并筛选 const storedData = JSON.parse(localStorage.getItem('your-storage-key')) || []; const matchedData = storedData.filter(item => { // 替换成你的匹配逻辑,比如匹配标题或内容 return item.title.includes(query); }); // 渲染卡片到容器 matchedData.forEach(item => { const card = document.createElement('div'); card.className = 'card'; // 自定义卡片内容,根据你的数据结构调整 card.innerHTML = ` <h3>${item.title}</h3> <p>${item.description}</p> `; searchResultsContainer.appendChild(card); }); });
方案2:用sessionStorage传递预处理后的查询结果
如果查询结果数据量不大,可以在原页面先处理好结果,存在sessionStorage后再跳转:
原页面的提交逻辑:
document.querySelector('#your-form-id').addEventListener('submit', function(e) { e.preventDefault(); const searchQuery = new FormData(this).get('search-input-name'); const storedData = JSON.parse(localStorage.getItem('your-storage-key')) || []; // 预处理筛选结果 const matchedData = storedData.filter(item => item.title.includes(searchQuery)); // 存入sessionStorage(注意数据量不要超过浏览器限制) sessionStorage.setItem('search-results-data', JSON.stringify(matchedData)); // 跳转页面 window.location.assign('results.html'); });results.html中的渲染逻辑:
document.addEventListener('DOMContentLoaded', function() { const searchResultsContainer = document.getElementById('search-results'); if (!searchResultsContainer) return; // 从sessionStorage读取结果 const matchedData = JSON.parse(sessionStorage.getItem('search-results-data')) || []; // 渲染卡片 matchedData.forEach(item => { const card = document.createElement('div'); card.className = 'card'; card.innerHTML = `<h3>${item.title}</h3>`; searchResultsContainer.appendChild(card); }); // 用完后清除sessionStorage中的数据,避免残留 sessionStorage.removeItem('search-results-data'); });
额外排查点
- 确保
results.html中确实存在id="search-results"的元素,且没有拼写错误 - 把
results.html中的JS代码放在<body>标签末尾,或者用DOMContentLoaded/load事件包裹,避免在DOM未加载完成时执行元素获取操作
内容的提问来源于stack exchange,提问作者internetdeveloperr
相关产品推荐
相关产品推荐

