脚本可执行却触发getComputedStyle参数非Element错误,节点列表疑问
问题原因分析
这个问题我之前也碰到过,其实根源不在live node list本身,而是你用错了遍历方式~
document.getElementsByTagName("*")返回的确实是包含所有DOM元素的live HTMLCollection,但HTMLCollection是类数组对象,它除了包含索引对应的元素外,还自带一些可枚举的属性(比如length、item()、namedItem()等)。- 当你用
for(ii in target)遍历的时候,会把这些属性名也当作遍历项。比如当ii等于"length"时,target[ii]就是数字(集合的长度),而不是DOM元素;当ii是"item"时,target[ii]是一个函数。这些非Element类型的值传入getComputedStyle,自然就会抛出类型错误。
修正后的脚本方案
下面是几种可靠的遍历方式,能避开非元素项的问题:
方案1:普通for循环(兼容性最好)
var target = document.getElementsByTagName("*"); for (let ii = 0; ii < target.length; ii++) { const element = target[ii]; // 额外加个类型判断更稳妥,避免意外情况 if (element instanceof Element && window.getComputedStyle(element).position === 'fixed') { element.style.display = 'none'; console.log('it"s gone'); } }
方案2:for...of循环(现代浏览器推荐)
HTMLCollection在现代浏览器中是可迭代对象,用for...of可以直接遍历其中的元素,不会碰到额外属性:
const target = document.getElementsByTagName("*"); for (const element of target) { if (window.getComputedStyle(element).position === 'fixed') { element.style.display = 'none'; console.log('it"s gone'); } }
方案3:转成数组后遍历
把HTMLCollection转成普通数组,就可以用forEach等数组方法:
const target = Array.from(document.getElementsByTagName("*")); target.forEach(element => { if (window.getComputedStyle(element).position === 'fixed') { element.style.display = 'none'; console.log('it"s gone'); } });
补充说明
live node list本身的元素都是标准的Element类型,只是for...in的遍历逻辑会把对象的所有可枚举属性都列出来,才导致你拿到了非元素的项。只要换用正确的遍历方式,就能解决这个报错啦~
内容的提问来源于stack exchange,提问作者jf111
相关产品推荐
相关产品推荐

