Применить метод forEach к массиву, как объекты в JavaScript

Здесь у меня есть четыре кнопки ввода, и я хочу добавить обработчик событий для каждой из них. Если я использую цикл, мне приходится иметь дело с замыканиями. На самом деле я пытаюсь понять, как управлять методом forEach для массива, подобного объекту. Решение, которым я могу управлять. Как мы должны столкнуться с проблемой, связанной с закрытием, если мы хотим использовать методы массива. Мне пришлось использовать object.keys, чтобы получить индексы и применить к ним forEach. Хотя это звучит странно, но я не совсем удовлетворен этим решение. Может ли это быть проще? Как я могу управлять forEach непосредственно в nodeList, хранящемся в переменной Buttons

function change(){
    var buttons=document.getElementsByTagName('input');
    var keys=Object.keys(buttons);

    keys.forEach(function(el,indx,arr){
        if(el != 'length'){
            this[el].addEventListener('click', function(e){ 
                alert(e.target.value);
            });
        }
    }, buttons);
}

change();
<input type='button' value='button1'> 
<input type='button' value='button2'> 
<input type='button' value='button3'> 
<input type='button' value='button4'> 

2 ответа

Решение

document.getElementsByTagName возвращает вам "хост-объект". Эти объекты могут отличаться по поведению в разных браузерах.

buttons это NodeList, а не массив.Object.keysможет работать не так, как ожидалось, потому что он может иметьбольше свойств, чем просто индексы и length,

Документы для NodeList ( https://developer.mozilla.org/en-US/docs/Web/API/NodeList) содержат несколько примеров для преобразования его в массив и использования с.forEach,

Метод, который я обычно использую, не указан на странице документов. Я обычно использую:

var arr = Array.prototype.slice.call(buttons);

Посмотрите этот вопрос для получения дополнительной информации: Самый быстрый способ конвертировать JavaScript NodeList в массив?

Тогда вы можете сделать:

arr.forEach(function(el){
    el.addEventListener('click', function(e){ 
        alert(e.target.value);
    });
});

Вот демо:

var buttons = document.getElementsByTagName('input');
var arr = Array.prototype.slice.call(buttons);
arr.forEach(function(el) {
  el.addEventListener('click', function(e) {
    alert(e.target.value);
  });
});
<input type='button' value='button1'>
<input type='button' value='button2'>
<input type='button' value='button3'>
<input type='button' value='button4'>

Решение ES6

Метод ES6 Array.from может напрямую преобразовывать массивоподобный объект в массив:

    var buttons = document.getElementsByTagName('input');

    Array.from(buttons).forEach(el=>{
      el.addEventListener('click', e =>{
        alert(e.target.value);
      });
    });
<input type='button' value='button1'>
<input type='button' value='button2'>
<input type='button' value='button3'>
<input type='button' value='button4'>

Другие вопросы по тегам