Применить метод 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'>