Компактная запись .querySelectorAll()

173
08 февраля 2018, 19:02

Всем привет! Допустим есть код:

var btn = document.querySelectorAll('button'); 
btn[0].addEventListener('click', function() { 
  console.log(btn[0].textContent); 
}); 
btn[1].addEventListener('click', function() { 
  console.log(btn[1].textContent); 
}); 
btn[2].addEventListener('click', function() { 
  console.log(btn[2].textContent); 
});
<body> 
  <button>click me</button> 
  <button>click my</button> 
  <button>click im</button> 
</body>

Вопрос: Возможно ли написать более компактную запись: btn[i].addEventListener(..) (или что-то еще) чтобы не перечислять каждую по отдельности? Спасибо.

Answer 1

Возможно ли написать более компактную запись: btn[i].addEventListener(..)

Да, возможно, для этого надо использовать цикл for

var btn = document.querySelectorAll('button');
for(var i=0;i<btn.length;i++){
    btn[i].addEventListener(...)
}

При этом, чтобы внутри обработчика обращаться к нужной кнопке достаточно использовать для этого this

console.log(this.textContent);

var btn = document.querySelectorAll('button'); 
 
for (var i = 0; i < btn.length; i++) { 
  btn[i].addEventListener('click', function() { 
    console.log(this.textContent); 
  }); 
}
<body> 
  <button>click me</button> 
  <button>click my</button> 
  <button>click im</button> 
</body>

Answer 2

Во первых, querySelectorAll возвращает коллекцию, которую можно перебрать:

document.querySelectorAll('button') 
  .forEach(function(btn) { 
    btn.addEventListener('click', function() { 
      console.log(btn.textContent); 
    }) 
  });
<body> 
  <button>click me</button> 
  <button>click my</button> 
  <button>click im</button> 
 
</body>

Во вторых, можно обойтись одним обработчиком событий:

document.addEventListener('click', function(e) { 
  if(!e.target.matches('button')) return; 
  console.log(e.target.textContent); 
})
<body> 
  <button>click me</button> 
  <button>click my</button> 
  <button>click im</button> 
 
</body>

Answer 3

Можно кнопки перебрать.

let btn = document.querySelectorAll('button'); 
 
btn.forEach(c => { 
    c.addEventListener('click', () => { 
        console.log(c.textContent) 
    }) 
})
<button>click me</button> 
     <button>click my</button> 
     <button>click im</button>

Answer 4

Взято из learn.javascript.ru.

Если есть много элементов, события на которых нужно обрабатывать похожим образом, то вместо того, чтобы назначать обработчик каждому – ставится один обработчик на их общего предка. Из него можно получить целевой элемент event.target, понять на каком именно потомке произошло событие и обработать его.

Хороший пример обработчика и для абсолютно разных действий.

<div id="menu">
  <button data-action="save">Сохранить</button>
  <button data-action="load">Загрузить</button>
  <button data-action="search">Поиск</button>
</div>
<script>
  function Menu(elem) {
    this.save = function() {
      alert( 'сохраняю' );
    };
    this.load = function() {
      alert( 'загружаю' );
    };
    this.search = function() {
      alert( 'ищу' );
    };
    var self = this;
    elem.onclick = function(e) {
      var target = e.target;
      var action = target.getAttribute('data-action');
      if (action) {
        self[action]();
      }
    };
  }
  new Menu(menu);
</script>

про data атрибут тут

Answer 5

Возможно ли написать более компактную запись: btn[i].addEventListener(..)

Вполне, мне больше нравится через for-each, не смотря но то что это немного избыточно, по сравнению с обычным циклом по элементам NodeList:

Array.prototype.slice.call(document.querySelectorAll("button")) 
     .forEach(function(btn){ 
         btn.addEventListener('click', function() { 
             console.log(btn.textContent) 
         }); 
     });
<body> 
    <button>click me</button> 
    <button>click my</button> 
    <button>click im</button> 
</body>

READ ALSO
Каким образом делаются переходы?

Каким образом делаются переходы?

Как реализуются такие переходы, как на скриншоте?

198
Каким образом можно парсить SPA сайты?

Каким образом можно парсить SPA сайты?

Нужно спарсить инфу с сайтаПроблема в том, что он одностраничный (SPA)

160
Свойства объектов

Свойства объектов

Друзья, подскажите пожалуйста, почему в данном случае в obj3 свойству size присвоилось значение 40, а addheight осталась 50 по умолчанию в obj3, и как нужно...

245
Как получить макс высоту с padding?

Как получить макс высоту с padding?

Привет есть такая структура

212