В приведенном ниже коде

<!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;
}

Согласно отладке, функция обратного вызова для каждого element массива elements не выполняется при событии щелчка.

Я считаю elements коллекцией ключей, как показано ниже ..

enter image description here

-

Как устранить эту ошибку?

5
overexchange 16 Дек 2015 в 07:10

4 ответа

Лучший ответ

forEach не включен в прототип массива-подобного объекта HTMLCollection, возвращаемого getElementsByClassName.

Экземпляр HTMLCollection подобен массиву, в котором вы можете получить доступ к элементам по индексам, но он не включает в себя все методы массива, как вы обнаружили с помощью forEach.

Однако вы можете вручную вызвать метод объекта, обратившись к методу из прототипа Array.

var elements = document.getElementsByClassName('hide');
Array.prototype.forEach.call(elements, function(element){
    element.style.visibility = "hidden";
});
9
Alexander O'Mara 16 Дек 2015 в 04:29

Вы можете преобразовать elements в массив и затем вызвать forEach ().

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

Скрипка: https://jsfiddle.net/assx7hmh/

1
Ramanlfc 16 Дек 2015 в 04:16

Основываясь на вашем коде, вот мое решение:

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

Вам просто нужно перебрать объект, потому что forEach просто принимает массив.

0
omgpwned 16 Дек 2015 в 04:41

Метод forEach предназначен для массивов. Это не работает, потому что .getElementsByClassName() возвращает HTMLCollection.

Чтобы обойти это, используйте:

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

Или короче:

var elements = document.getElementsByClassName('hide');
[].forEach.call(elements, function(element){
    element.style.visibility = "hidden";
});
2
Josh Crozier 16 Дек 2015 в 04:12