执行JS代码时触发Cannot read property 'toLowerCase'错误,求解决办法
解决Cannot read property 'toLowerCase'错误的可行思路
兄弟,这个报错其实很好定位——本质是你默认每个<h3>的firstChild一定是能取出有效文本的节点,但实际页面里的<h3>可能不符合这个假设。咱们一步步理清楚:
错误根源
你遇到的Cannot read property 'toLowerCase' of undefined,意味着代码里tags[i].firstChild.nodeValue返回了undefined,常见场景有两种:
- 某个
<h3>是空标签,比如<h3></h3>,它的firstChild是null,调用nodeValue自然拿不到值; <h3>的第一个子节点不是文本节点,比如<h3><span>标题内容</span></h3>,这时候firstChild是<span>元素节点,它的nodeValue本身就是undefined。
方案1:用textContent获取文本(最可靠)
直接获取<h3>的所有文本内容,不管内部有没有嵌套元素,同时处理空文本的情况:
(function() { var tags = document.getElementsByTagName("h3"), l = tags.length, i, newid, n, textContent; for( i=0; i<l; i++) { // 获取h3的纯文本并去除首尾空白 textContent = tags[i].textContent.trim(); // 处理空文本的情况,生成默认ID if (!textContent) { newid = 'h3-' + (i+1); } else { newid = textContent.toLowerCase().replace(/[^a-z0-9-]/g,'-').replace(/--+/g,'-'); } // 处理ID重复逻辑不变 if( document.getElementById(newid)) { n = 1; do {n++;} while(document.getElementById(newid+'-'+n)); newid += '-'+n; } tags[i].id = newid; } })();
方案2:严格校验firstChild的有效性
如果你坚持要基于firstChild处理,可以先做节点类型和值的校验:
(function() { var tags = document.getElementsByTagName("h3"), l = tags.length, i, newid, n, nodeValue; for( i=0; i<l; i++) { var firstChild = tags[i].firstChild; // 校验:节点存在 + 是文本节点 + 文本内容非空白 if (!firstChild || firstChild.nodeType !== 3 || !(nodeValue = firstChild.nodeValue.trim())) { newid = 'h3-' + (i+1); } else { newid = nodeValue.toLowerCase().replace(/[^a-z0-9-]/g,'-').replace(/--+/g,'-'); } // 重复ID处理逻辑不变 if( document.getElementById(newid)) { n = 1; do {n++;} while(document.getElementById(newid+'-'+n)); newid += '-'+n; } tags[i].id = newid; } })();
额外调试小技巧
可以在循环里加一行console.log(tags[i], tags[i].firstChild),直接在控制台看哪个<h3>触发了问题,能更针对性地调整代码逻辑。
内容的提问来源于stack exchange,提问作者simondlh
相关产品推荐
相关产品推荐

