Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript getElementByClass().foreach function 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>';
like image 504
Jousi Avatar asked Dec 14 '22 02:12

Jousi


1 Answers

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:

  • For-each over an array in JavaScript? (some answers there -- including mine -- have a section on "array-like" things, which includes HTMLCollections)
  • What do querySelectorAll, getElementsByClassName and other getElementsBy* methods return?
like image 64
T.J. Crowder Avatar answered Jan 13 '23 23:01

T.J. Crowder