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 </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 </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 fromdocument
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 todocument
– 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
1 Answer
Reset to default 4You 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.