5

In the below code,

<!DOCTYPE html>
<html>
    <head>
        <title>Hide odd rows</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <div style="background-color:#8F9779;width:200px;height:30px;">
        </div>
        <hr style="width:200px" align="left">
        <table border="1" >
            <tr class="hide" >
                <td width="40" height="20">row 1</td>
            </tr>
            <tr>
                <td width="40" height="20">row 2</td>
            </tr>
            <tr class="hide">
                <td width="40" height="20">row 3</td>
            </tr>
            <tr>
                <td width="40" height="20">row 4</td>
            </tr>
            <tr class="hide">
                <td width="40" height="20">row 5</td>
            </tr>
        </table><br>
        <button type="button" name="HideRows">Hide Odd Rows</button>
        <script type="text/javascript" src="hideOddRows.js"></script>
    </body>
</html>

/* hideOddRows.js */
document.querySelector('[name=HideRows]').onclick = hideRows;

function hideRows(){
    var elements = document.getElementsByClassName('hide');
    elements.forEach(function(element){
        element.style.visibility = "hidden";
    });
    return true;
}

As per debugging, callback function for each element of elements array is not executing on click event.

I consider elements as keyed collection, as shown below..

enter image description here

--

How to resolve this error?

1
  • elements has nodelist and forEach does not work with nodelist. Try [].forEach.call(elements,function(item){}); Commented Dec 16, 2015 at 4:11

4 Answers 4

9

forEach is not included in the prototype of the array-like HTMLCollection object returned by getElementsByClassName.

An HTMLCollection instance is array-like, in that you can access elements by indexes, but it does not include all of the methods of an array, as you have discovered with forEach.

You can however manually call the method on the object by accessing the method from the Array prototype.

var elements = document.getElementsByClassName('hide');
Array.prototype.forEach.call(elements, function(element){
    element.style.visibility = "hidden";
});
Sign up to request clarification or add additional context in comments.

2 Comments

What is the story about return true? You didn't use it. Is it a must to say return true in callback and event handlers? Can't I say return 1 or return 23?
@overexchange In your case, it means allow the default behavior. I excluded it from my sample, as it's not directly related to the forEach issue. See this answer for more info: stackoverflow.com/a/128966/3155639
2

The forEach method is for arrays. It's not working because .getElementsByClassName() returns an HTMLCollection.

To work around this, use:

var elements = document.getElementsByClassName('hide');
Array.prototype.forEach.call(elements, function(element){
    element.style.visibility = "hidden";
});

or shorter:

var elements = document.getElementsByClassName('hide');
[].forEach.call(elements, function(element){
    element.style.visibility = "hidden";
});

1 Comment

I would recommend avoiding the shorter alternative, as it makes an unused array instance.
1

you can convert elements to an array and then call forEach().

 var elements = document.getElementsByClassName('hide');
 elements = Array.prototype.slice.call(elements,0);
    elements.forEach(function(element){
        element.style.visibility = "hidden";
    });

fiddle :https://jsfiddle.net/assx7hmh/

Comments

0

Base on your code, here is my solution:

function hideRows(){
  var elements = document.getElementsByClassName('hide');
  for(var key in elements) {
    if(elements.hasOwnProperty(key))
      elements[key].style.visibility = "hidden";
  }
  return true;
}

You just need to loop through object because forEach just accept array.

2 Comments

But using for..in adds an extra check of enumerability.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.