【问题标题】:HTML getElementsByClassName returns HTMLCollection with length of 0HTML getElementsByClassName 返回长度为 0 的 HTMLCollection
【发布时间】:2015-11-12 20:10:25
【问题描述】:

我正在尝试使用js document.getElementsByClassName 来定位一个html元素,它实际上是一个表格的标题。

对于以下代码:

console.log(document.getElementsByClassName('gtableheader'));

Firebug,我可以看到它记录了一个HTMLCollection,当我点击它时,它显示:

-> 0         tr.gtableheader
   length    1

所以它确实找到了我想要的元素。

但是当我使用时:

console.log(document.getElementsByClassName('gtableheader').length);

那么输出是0。太奇怪了,有什么想法吗?

【问题讨论】:

标签: javascript html dom


【解决方案1】:

这是因为getElementsByClassName 返回一个live 集合。对象的length 属性是0,因为在那个时间点,DOM 中没有具有该类名的元素。由于控制台显示对象的实时表示,因此当元素添加到 DOM 时,它会显示所有匹配的元素。

DOM 解析器从上到下解析文档,当它到达一个标签时,它会解析它并将它的 DOM 表示(HTMLElement 接口的一个实例)添加到文档对象模型中。您应该将脚本标签移动到 body 标签的末尾,或者监听在初始 HTML 文档完全加载和解析时触发的 DOMContentLoaded 事件。

【讨论】:

  • “那是因为getElementsByClassName返回一个LIVE集合”应该用h1标签字体写。这是一个非常重要的事实。
【解决方案2】:

使用getElementsByClassName() 会将文档中具有该类名的所有元素作为NodeList 返回。该对象表示可以通过索引号访问的节点集合,索引号从 0 开始。为了访问 NodeList 中的元素,您必须使用循环。

当您console.log(document.getElementsByClassName('gtableheader').length); 时,您会看到 0,因为当您运行它时,没有类为 gtableheader 的元素。您可以在控制台中看到这些项目,因为 document.getElementsByClassName() 返回一个实时集合,该集合会在添加新元素时更新。

同样,在您使用的代码中,长度为0,您可以使用下面的代码来访问类名。

document.getElementsByClassName('gtableheader')[0].style.color="red";

如果要访问类中的所有元素,可以使用 for 循环。

var x = document.getElementsByClassName('gtableheader');
for (var i = 0; i < x.length; i++) {
    x[i].style.color = "red";
}

更多信息: http://www.w3schools.com/jsref/met_document_getelementsbyclassname.asp

【讨论】:

  • 这似乎没有回答这个问题。您还引用了getElementsByClassName 返回的nodeList 的长度属性——您只需从分配结果的变量x 中读取它。当我对这个只有一个元素的页面运行 document.getElementsByClassName('question').length 时,结果是 1。所以,你没有回答为什么 OP 的问题中的 length 属性返回 0。
  • 是的,实际上,真正的问题是我尝试在加载之前访问element,这就是长度为0的原因。
  • 另一个问题是element 没有style 属性。它可以工作,但 IDE 一直抱怨它应该是 HTMLElement。如何解决?
  • 谢谢,文档中的更多代码可以让它工作。但这在逻辑上很奇怪 var xyz= document.getElementsByClassName('xyz');控制台.log(xyz);控制台.log(xyz.length);。我分配首先获取组元素,然后读取变量的长度,但它仍然返回 0。它是 javascript... :)
  • document.getElementsByClassName 是创建一个新的 HTMLCollection 还是简单地返回一个现有的?
【解决方案3】:

使用它来使其工作

window.addEventListener("load", function(event) {
    console.log(document.getElementsByClassName('gtableheader').length);
});

【讨论】:

    【解决方案4】:

    我遇到了类似的问题,但这里的其他答案并没有导致我的解决方案。我最终意识到,在我的代码运行时,DOM 还没有完全构建,因此是空数组。我在控制台中看到的填充数组是在 DOM 完全形成并且脚本完成之后存在的。

    对我有用的是将需要数组的代码包装在 MutationObserver 中,并将其设置为观看包含将动态生成的部分的硬编码 div(参见 StackOverflow answerMDN documentation)。

    试试这个:

    var divArray = document.getElementById('hardCodedContainer');
    
    var observer = new MutationObserver(function(){
       console.log(document.getElementsByClassName('gtableheader').length);
       console.log(document.getElementsByClassName('gtableheader'));
    };
    
    observer.observe(divArray, { attributes: false, childList: true, subtree: true });
    
    // When you've got what you need, you should call this function to trigger a disconnect 
    function classesFound(){
       observer.disconnect();
    };
    

    【讨论】:

      【解决方案5】:

      只需要在声明类的html代码之后调用js文件即可。

      【讨论】:

      • 你是怎么做到的
      • 非常模糊和笼统。重构或删除您的评论
      猜你喜欢
      • 2013-01-08
      • 2016-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-11
      • 1970-01-01
      • 2020-09-21
      • 2017-07-17
      相关资源
      最近更新 更多