I want to iterate over the results of
document.getElementsByTagName("...");
It returns an HTMLCollection
, not an array. So I can't simply use forEach
.
The following is possible but doesn't look very nice:
let elements = document.getElementsByTagName("...");
for (var i = 0, m = elements.length; i < m; i++) {
let element = elements[i];
}
For javascript, there exists pretty much the exact same question: For loop for HTMLCollection elements
And apparently, with the latest updates, modern browsers support:
var list = document.getElementsByClassName("events");
for (let item of list) {
log(item.id);
}
But the typescript compiler complains:
error TS2495: Type 'NodeListOf<HTMLParagraphElement>' is not an array type or a string type.
It still transpiles to proper Javascript though. It's even aware of what I'm doing here and doesn't just copy over the sourcecode. The compiled output is this:
var elements = main_div.getElementsByTagName("p");
for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
var element = elements_1[_i];
}
This is great, since the generated code will be supported even on older browsers. But I would like to get rid of the error message.
My compilerOptions are this:
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"sourceMap": true,
"rootDir": "src",
"lib": [
"es2015",
"dom"
]
}
}
I did try to edit my lib options. This specific feature was a part of ES6 and has been reworked a few times. So I tested the various ecmascript versions in lib but couldn't find a working setup.
There are 3 methods that can be used to properly loop through an HTMLCollection. Method 1: Using the for/of loop: The for/of loop is used to loop over values of an iterable object. This includes arrays, strings, nodeLists, and HTMLCollections. The syntax of this loop is similar to the for/in loop.
An HTMLCollection is a collection of document elements. A NodeList is a collection of document nodes (element nodes, attribute nodes, and text nodes). HTMLCollection items can be accessed by their name, id, or index number. NodeList items can only be accessed by their index number.
To iterate over the selected elements, you can use forEach() method (supported by most modern web browsers, not IE) or just use the plain old for-loop.
An HTMLCollection is an array-like collection (list) of HTML elements. The elements in a collection can be accessed by index (starts at 0). The length Property returns the number of elements in the collection.
You can convert it to an array if you want to use forEach
const elements: Element[] = Array.from(document.getElementsByTagName("..."));
elements.forEach((el: Element) => {
// do something
})
The typescript compiler supports this after specifying an extra flag, downlevelIteration
:
{
"compilerOptions": {
"target": "es5",
"downlevelIteration": true
}
}
However, this will not only remove the error, it will also change the compiler output. This input typescript:
function compileTest(){
let elements = document.getElementsByTagName("p");
for(let element of elements){
console.log(element);
}
}
is compiled to this javascript:
function compileTest() {
var e_1, _a;
var elements = document.getElementsByTagName("p");
try {
for (var elements_1 = __values(elements), elements_1_1 = elements_1.next(); !elements_1_1.done; elements_1_1 = elements_1.next()) {
var element = elements_1_1.value;
console.log(element);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (elements_1_1 && !elements_1_1.done && (_a = elements_1.return)) _a.call(elements_1);
}
finally { if (e_1) throw e_1.error; }
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With