最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - HTMLCollection appearing in console with many elements but has length 0 - Stack Overflow

programmeradmin0浏览0评论

There are a bunch of span elements on the page that I'm trying to grab that are formatted like so:

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

So, I decided to select them using getElementsByClassName() and then iterate over this HTMLCollection, which when I view in the developer console shows 32 items but when I check the length property it is 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?

I must be missing something with how getElementsByClassName or HTMLCollections in general work, but I can't seem to figure it out through docs or Google at this point.

As far as I understand things, if I'm seeing all of those span elements as part of the console.log statement, they should be contributing to the length of the eventToClick HTMLCollection and I should be able to iterate over it with a for loop, but this does not work! Is the developer console performing some sort of witchcraft here, and I don't really have these elements as part of an HTMLCollection?

Here is a live version so you can replicate in your own browser: .html

Posting a second image of the span elements in the console for one of the people helping out with this issue.

Working Solution, but not great!

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);
    }
  }
});

As Harshal noted in the accepted answer, I was not able to grab the elements because my script was executing before they were loaded onto the page. The Google scripts which are loading this calendar data are really plex, and stepping through them with the debugger hasn't yielded a place where I can logically see the elements being added, so I tried using an interval timer to check for the presence of the elements with the class name I was looking for.

That seems to do the trick for now, I'm open to more graceful solutions if you have any! Still researching this...

There are a bunch of span elements on the page that I'm trying to grab that are formatted like so:

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

So, I decided to select them using getElementsByClassName() and then iterate over this HTMLCollection, which when I view in the developer console shows 32 items but when I check the length property it is 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?

I must be missing something with how getElementsByClassName or HTMLCollections in general work, but I can't seem to figure it out through docs or Google at this point.

As far as I understand things, if I'm seeing all of those span elements as part of the console.log statement, they should be contributing to the length of the eventToClick HTMLCollection and I should be able to iterate over it with a for loop, but this does not work! Is the developer console performing some sort of witchcraft here, and I don't really have these elements as part of an HTMLCollection?

Here is a live version so you can replicate in your own browser: http://danielschroedermusic./apps/cal-test/cal.html

Posting a second image of the span elements in the console for one of the people helping out with this issue.

Working Solution, but not great!

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);
    }
  }
});

As Harshal noted in the accepted answer, I was not able to grab the elements because my script was executing before they were loaded onto the page. The Google scripts which are loading this calendar data are really plex, and stepping through them with the debugger hasn't yielded a place where I can logically see the elements being added, so I tried using an interval timer to check for the presence of the elements with the class name I was looking for.

That seems to do the trick for now, I'm open to more graceful solutions if you have any! Still researching this...

Share Improve this question edited Oct 4, 2017 at 3:46 djs asked Oct 3, 2017 at 21:52 djsdjs 4,0653 gold badges17 silver badges28 bronze badges 5
  • 1 Needs more minimal reproducible example. – melpomene Commented Oct 3, 2017 at 21:55
  • @melpomene just uploaded to live site, does that satisfy? – djs Commented Oct 3, 2017 at 21:59
  • When do these elements get added? HTMLCollection is a live collection. Meaning any elements added/removed from document will be reflected in that collection. So while the log showed length 0, by the time you expand the HTMLCollection in the console it has updated to contain new elements added to document – Patrick Evans Commented Oct 3, 2017 at 21:59
  • That looks horribly plicated. – melpomene Commented Oct 3, 2017 at 22:05
  • @melpomene I agree, this is just a silly side project to see if I can pull calendar info from an iCal embed and then reformat however I see fit. It seems like I should be able to get the HTMLCollection doing the method I've used though, that's what is stumping me. – djs Commented Oct 3, 2017 at 22:13
Add a ment  | 

1 Answer 1

Reset to default 4

You need to do document.getElementsByClassName('te-s') after the calendar is loaded.

The 32 you are seeing before is correct. It is showing you object of HTMLCollection which is reference to the array. So when the eventToClick is printed, it has zero values in it .. put a debugger and see it. But after the calendar is loaded the eventToClick is showing you all the values. The reason why the length is 0 is same. The length shown is pass-by-value. So when you requested it, the length was actually 0.

There must be some callback function after the calendar is loaded which you can use to get the correct value, you can get correct length over there.

If you need help in this let me know the calendar library you are using, would love to research on it.

发布评论

评论列表(0)

  1. 暂无评论