JavaScript页面故障求助:rendering_list调用位置问题解析
我是JavaScript初学者,正在开发一个包含输入框、保存按钮、删除按钮和列表的网页:用户输入内容点击保存后,内容会显示在列表中,刷新页面后历史输入仍能保留。但我遇到了代码执行的问题:
rendering_list(JSON.parse(localStorage.getItem("Note")))
当把这行函数调用放在代码当前位置时,整个页面无法正常工作;但将它移到代码末尾时,页面就能正常运行。想知道问题的底层原因。
附上完整代码:
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> <link rel="stylesheet" href="leadChromeExtension.css"> </head> <body> <input type="text"> <div> <button id="lead_saving">Save lead</button> <button id="lead_deleting">Delete lead</button> </div> <ul></ul> <script src="leadChromeExtension.js"></script> </body> </html>
CSS代码
*{ margin: 0; box-sizing: border-box; } body{ min-height: 100vh; padding-top: 10px; padding-left: 10px; } input{ width: 300px; margin-bottom: 10px; }
JavaScript代码
let lead_list=[] let input_field = document.querySelector("input") let saving = document.getElementById("lead_saving") let deleting = document.getElementById("lead_deleting") let ul_el = document.querySelector("ul") rendering_list(JSON.parse(localStorage.getItem("Note"))) function clearing_Storage(){ localStorage.clear() } deleting.addEventListener("click",clearing_Storage) function rendering_list(list){ let HTML_text = "" for (i=0; i < list.length; i=i+1){ HTML_text = HTML_text + `<li> <a href = ${list[i]}> ${list[i]}</a> </li>` ul_el.innerHTML = HTML_text } } saving.addEventListener("click",function(){ HTML_text = "" lead_list.push(input_field.value) input_field.value="" localStorage.setItem("Note",JSON.stringify(lead_list)) rendering_list(lead_list) })
空localStorage触发的类型错误
页面首次加载时,localStorage中不存在"Note"键,localStorage.getItem("Note")会返回null,经过JSON.parse(null)处理后结果依然是null。此时调用rendering_list(null),函数内部尝试访问list.length(即null.length),会直接抛出TypeError: Cannot read properties of null (reading 'length')错误。JavaScript的错误中断机制
JavaScript是单线程执行环境,一旦脚本执行中出现未捕获的错误,后续所有代码都会停止执行。你的代码中,rendering_list的调用放在事件监听绑定代码之前,错误抛出后,deleting.addEventListener和saving.addEventListener根本不会执行,导致按钮点击完全无响应,看起来整个页面失效。放在代码末尾能运行的逻辑
如果把rendering_list的调用移到代码最后,错误抛出前,事件监听的代码已经执行完毕,按钮的点击功能已经绑定完成。虽然渲染列表时仍会报错,但页面核心的保存、删除功能不受影响,所以会觉得页面可以正常运行。
另外还有一个次要问题:rendering_list函数中的循环变量i未用let声明,会成为全局变量,可能引发意外问题,但这不是页面失效的直接原因。
只需要在调用rendering_list时,先判断传入的值是否为null,如果是就传入空数组,避免访问null.length:
// 替换原来的调用行 rendering_list(JSON.parse(localStorage.getItem("Note")) || [])
同时建议给循环变量i加上let声明,避免全局变量污染:
function rendering_list(list){ let HTML_text = "" // 给i加上let声明 for (let i=0; i < list.length; i=i+1){ HTML_text = HTML_text + `<li> <a href="${list[i]}" target="_blank"> ${list[i]}</a> </li>` ul_el.innerHTML = HTML_text } }
内容的提问来源于stack exchange,提问作者Trung Lương

