Jousi
Jousi

Reputation: 476

getElementsByClassName().forEach() function in JavaScript not working

I am trying to get each element of HTML by Class name with JavaScript and then change its height and width according to the value in a range object onchange.

The browser is showing an error: document.getElementsByClassName(...).forEach is not a function

But I tried to structure it every way possible and still nothing.

This is how my first JavaScript code looked like:

function updateInput(val) {
    document.getElementById('valueInput').innerHTML=val; /*This is just to show the value to the user*/
    document.getElementsByClassName('oneResult').forEach(functio‌​n changeWidth(element) { element.style.width = val + 'px'; } );
    document.getElementsByClassName('oneResult').forEach(functio‌​n changeWidth(element) { element.style.height = val + 'px'; } );
}

Then I tried this:

function updateInput(val) {
    document.getElementById('valueInput').innerHTML=val;
    function oneResultWH(element) {
        element.style.width = val + 'px';
        element.style.height = val + 'px';
    }
    document.getElementsByClassName('oneResult').forEach(oneResultWH);
}

But still no luck.

This is how my PHP looks like:

print '<div class="oneResult" style="background-image:url(Pictures/'.$img.'); height: 100px; width:100px; ">
<a id="word'. $x .'">'. $textConversion[$x] .'</a></div>';

Upvotes: 4

Views: 4482

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1075755

The browser is showing an error: document.getElementsByClassName(...).forEach is not a function

That's because getElementsByClassName doesn't return an array, it returns an HTMLCollection. They don't have a forEach method (yet; it may at some point, or not).

You can use the one that arrays have like this:

Array.prototype.forEach.call(document.getElementsByClassName("oneResult"), function(element) {
    // Use `element` here
});

Or on modern browsers (or with a polyfill) you can create an array from the collection:

Array.from(document.getElementsByClassName("oneResult")).forEach(function(element) {
    // Use `element` here
});

Another option is to add forEach to HTMLCollection, which you can do like this on any vaguely-modern browser (even IE8, if you polyfill Array.prototype.forEach first):

if (typeof HTMLCollection !== "undefined" && HTMLCollection.prototype && !HTMLCollection.prototype.forEach) {
    Object.defineProperty(HTMLCollection.prototype, "forEach", {
        value: Array.prototype.forEach,
        configurable: true,
        writable: true
    });
}

Finally, note that while HTMLCollection doesn't have forEach, the NodeList returned by querySelectorAll does, though on some older browsers it may need to be polyfilled. See this answer about polyfilling NodeList if necessary.

More:

Upvotes: 12

Related Questions