为何JS中innerHTML可访问DOM元素,自定义嵌套UL函数却报错?
DOM嵌套UL生成异常问题分析与解决
问题背景
页面DOM元素:
<div id="report"></div>
尝试将过滤后的csvData数组转为嵌套UL插入该div的代码:
let arr = csvData.filter(row => unchecked.includes(row[0])) console.log(arr); const div = document.getElementById("report"); const prepareUL = (root, arr) => { let ul = document.createElement('ul'); let li; root?.appendChild(document.createElement('ul')); arr.forEach(function(item) { if (Array.isArray(item)) { prepareUL(li, item); return; }; li = document.createElement('li'); li.appendChild(document.createTextNode(item)); ul.appendChild(li); }); } prepareUL(div, arr);
遇到的问题:
- 不检查
root是否存在时,会出现读取undefined的appendChild属性错误 - 直接用
div.innerHTML = arr能正常填充div - 替换为手动定义的简单数组时,自定义函数能正常工作
问题根源
1. 函数内的ul未关联到传入的root
代码里root?.appendChild(document.createElement('ul'))是新建了一个空的ul,但函数内声明的ul变量是另一个独立的ul元素,完全没挂载到root上,等于白创建。最终生成的列表结构根本没被添加到页面DOM中。
2. 嵌套数组处理时li未初始化
当遍历到数组元素时,如果此时li还没被赋值(比如过滤后的csvData第一个元素就是数组,或者前一个元素也是数组),li会是undefined,调用prepareUL(li, item)时传入的root就是undefined,自然会触发appendChild读取错误。
而手动定义的数组第一个元素是字符串,此时li会被正常创建并赋值,后续处理嵌套数组时li是有效的DOM元素,所以函数能正常运行;div.innerHTML = arr本质是把数组转成逗号分隔的字符串,不需要处理嵌套逻辑,只要div存在就能完成赋值,因此不会暴露函数里的逻辑问题。
修正后的代码
let arr = csvData.filter(row => unchecked.includes(row[0])) console.log(arr); const div = document.getElementById("report"); const prepareUL = (root, arr) => { if (!root) return; // 提前拦截无效root,避免后续报错 const ul = document.createElement('ul'); root.appendChild(ul); // 将函数内创建的ul挂载到传入的root上 arr.forEach(item => { if (Array.isArray(item)) { // 嵌套数组需要先创建一个li作为容器,再递归生成子列表 const nestedLi = document.createElement('li'); ul.appendChild(nestedLi); prepareUL(nestedLi, item); return; } const li = document.createElement('li'); li.textContent = item; // 简化文本节点创建 ul.appendChild(li); }); } prepareUL(div, arr);
内容的提问来源于stack exchange,提问作者chris
相关产品推荐
相关产品推荐

