【问题标题】:HTMLCollection appearing in console with many elements but has length 0HTMLCollection 出现在控制台中,包含许多元素,但长度为 0
【发布时间】:2017-10-03 21:52:22
【问题描述】:

我试图抓取的页面上有一堆 span 元素,它们的格式如下:

<div class="ca-evp1 te" style="color:#2952A3">
    <span class="te-t">11am&nbsp;</span>
    <span class="te-s">Antoine Diel</span>
</div>

所以,我决定使用 getElementsByClassName() 来选择它们,然后遍历这个 HTMLCollection,当我在开发者控制台中查看它时显示 32 个项目,但当我检查长度属性时它是 0。

  var toType = function(obj) {
    return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
  }
  var eventToClick = document.getElementsByClassName('te-s');
  console.log(eventToClick); // shows 32 elements
  console.log(toType(eventToClick)); //htmlcollection
  console.log(eventToClick.length); // 0...huh?

我一定错过了 getElementsByClassName 或 HTMLCollections 在一般工作中的工作方式,但目前我似乎无法通过 docs 或 Google 弄清楚。

据我了解,如果我将所有这些 span 元素视为 console.log 语句的一部分,它们应该会影响 eventToClick HTMLCollection 并且我应该能够使用 for 循环对其进行迭代,但这不起作用!开发者控制台是否在这里执行某种巫术,而我并没有真正将这些元素作为 HTMLCollection 的一部分?

这是一个实时版本,因此您可以在自己的浏览器中复制:http://danielschroedermusic.com/apps/cal-test/cal.html

在控制台中为帮助解决此问题的人发布第二张 span 元素的图片。

可行的解决方案,但不是很好!

document.addEventListener('DOMContentLoaded', function(event) {
  var intervalID = window.setInterval(myCallback, 50);
  function myCallback() {
    var eventToClick = document.getElementsByClassName('te-s');
    if (eventToClick.length > 0) {
      console.log(eventToClick);
      for (var i = 0; i < eventToClick.length; i++) {
        console.log(eventToClick[i]); // 32 elements!
      }
      clearInterval(intervalID);
    }
  }
});

正如 Harshal 在接受的答案中指出的那样,我无法抓取这些元素,因为我的脚本在它们加载到页面上之前正在执行。正在加载此日历数据的 Google 脚本非常复杂,并且使用调试器单步执行它们并没有产生一个我可以在逻辑上看到正在添加的元素的地方,所以我尝试使用间隔计时器来检查是否存在具有我正在寻找的类名的元素。

目前看来这可以解决问题,如果您有任何更优雅的解决方案,我愿意接受!还在研究这个...

【问题讨论】:

  • @melpomene 刚刚上传到现场,满意吗?
  • 什么时候添加这些元素? HTMLCollection 是现场合集。这意味着从document 添加/删除的任何元素都将反映在该集合中。因此,虽然日志显示长度为 0,但当您在控制台中展开 HTMLCollection 时,它已更新为包含添加到 document 的新元素
  • 这看起来非常复杂。
  • @melpomene 我同意,这只是一个愚蠢的项目,看看我是否可以从 iCal 嵌入中提取日历信息,然后重新格式化,但我认为合适。看起来我应该能够让 HTMLCollection 执行我使用过的方法,但这就是让我难过的原因。

标签: javascript htmlcollection


【解决方案1】:

日历加载完成后需要document.getElementsByClassName('te-s')

您之前看到的 32 是正确的。它向您显示 HTMLCollection 的对象,它是对数组的引用。因此,当打印eventToClick 时,它的值为零.. 放置一个调试器并查看它。但是在加载日历后,eventToClick 会向您显示所有值。长度为0 的原因是一样的。显示的长度是按值传递的。所以当你请求它时,长度实际上是0

日历加载后必须有一些回调函数,你可以使用它来获取正确的值,你可以在那里得到正确的长度。

如果您在这方面需要帮助,请告诉我您正在使用的日历库,很乐意研究它。

【讨论】:

  • 有道理,我会四处挖掘,看看这是否有效,然后回复你。
  • @Daniel.Schroeder 如果您需要帮助,请告诉我! ;) 我喜欢使用日历
  • 好的,这绝对是问题所在。我还没有找到一种优雅的方式来在加载元素后抓取它们,因为 Google 脚本正在对 onload 事件执行各种魔法,并且由于所有包含的脚本和疯狂的函数调用,单步调试器让我无处可去。我能够使用 setInterval 获取元素,并等到对 getElementsByClassName 的调用返回一些元素。现在,这就是我要做的!
猜你喜欢
  • 2020-08-27
  • 2023-03-06
  • 2018-12-10
  • 2020-11-18
  • 2018-12-02
  • 1970-01-01
  • 1970-01-01
  • 2019-11-23
  • 2019-11-08
相关资源
最近更新 更多