Reputation: 637
I have looked at almost every question that has been asked here about htmlcollection.
So I have a div and I am fetching data and creating divs inside this div with ajax so they are not hardcoded.
this is how div look like before I fetch the data
<div id="tivvits"></div>
this is how div#tivvits looks like after I call function show_all_tivvits(); show_all_tivvits() is a function where I create a ajax request and create new divs such as div#tivvit-21, div#tivvit-22, etc.
<div id="tivvits">
<div id="tivvit-19" class="grid-container">...</div>
<div id="tivvit-20" class="grid-container">...</div>
</div>
this is part of the js file
document.addEventListener("DOMContentLoaded", function(){
show_all_tivvits();
var t = document.getElementById('tivvits');
const j = t.getElementsByClassName("grid-container");
const k = Array.prototype.slice.call(j)
console.log(k);
for (var i = 0; i < k.length; i++) {
console.log(k[i]);
}
});
what I wanted to do in show_all_tivvits() function is I want to get the divs that are already in the div#tivvits and that way I am not gonna create them again but the problem is when I use console.log()
to print out document.getElementById('tivvits').getElementsByClassName('grid-container')
there are items in the htmlcollection but when I print out length it returns 0.
one more thing when I open inspect>source in chrome my index.php doesn't have updated div#tivvits. I have tried almost every way to loop this htmlcollection but it is not working.
list of things I have tried;
Array.from(links)
Array.prototype.slice.call(links)
[].forEach.call(links, function (el) {...});
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
HTMLCollection.prototype.forEach = Array.prototype.forEach;
Upvotes: 0
Views: 3283
Reputation: 5496
The HTMLCollection
object has a method - item()
which can be used to loop through the elements in the collection. The item()
method returns the element located at the specified offset from the collection. Example:
const gridContainers = document.getElementsByClassName("grid-container");
for (let i = 0; i < gridContainers.length; i++) {
console.log(gridContainers.item(i));
}
Upvotes: 0
Reputation: 178375
The world has moved on.
The older versions
const arrayLikeCollection = Array.prototype.slice.call(htmlCollection)
and
[].forEach.call(htmlCollection, function (el) {...});
could be written
[...htmlCollection].arrayMethod(....)
Then we got an update to htmlCollection so it supported .forEach out of the box. However the OTHER array methods like map, filter, some and every still needs the hmtlCollection to be cast to an arrayLike collection.
In 2024, the consensus is to use Array.from due to the very descriptive name.
It is my method of choice too now, since the array spread can generate annoying errors if your statement on the line above does not have a semicolon:
const collection = document.querySelectorAll('.someClass')
[...collection].someMethod(...) // the [] is seen as belonging to the line before
So here is the currently recommended way
window.addEventListener("DOMContentLoaded", () => { // when the elements are available
const getIds = () => {
const gridContainers = document.querySelectorAll("#tivvits .grid-container");
const ids = Array.from(gridContainers).map(div => div.id);
return ids;
};
const idsAtLoadTime = getIds(); // can be called elsewhere, like at the end of an AJAX call
console.log(idsAtLoadTime)
});
<div id="tivvits">
<div id="tivvit-19" class="grid-container">...</div>
<div id="tivvit-20" class="grid-container">...</div>
</div>
Upvotes: 2
Reputation: 24930
It's not really clear, but are you looking for something like this?
targets = document.querySelectorAll('#tivvits > .grid-container')
for (let target of targets)
{console.log(target.id)}
This should select all <div>
nodes which are direct children of the <div id="tivvits">
node and have a class
attribute with the value "grid-container"
, and extract from them the attribute value of the id
attribute.
Upvotes: 3