Умное использование событий

Тарасов, GeekBrains

by shurikation

HTML

<div class="wrap">
  <p>Товар 1</p>
  <button data-price="500">Кнопка 1</button>
  
   <p>Товар 2</p>
  <button data-price="100">Кнопка 2</button>
  
   <p>Товар 3</p>
  <button data-price="300">Кнопка 3</button>
  
</div>

JavaScript

const elems = document.querySelectorAll('button');

for (const elem of elems) {
  elem.addEventListener('click', () => {
    alert('Что-то делает');
  })
} 

//При нажатии на кнопку всплывает alert
//Но! На каждой итерации цикла for заново создаётся НОВАЯ функция. Это не очень хорошо для памяти. Поэтому функцию надо вынести и заранее определить:

function myFunc() {
  alert('Что-то делает');
}

const elems2 = document.querySelectorAll('button');

for (const elem of elems2) {
  elem.addEventListener('click', myFunc); //myFunc БЕЗ круглых скобок. Иначе - функция бы выполнилась и вернула результат работы - в данном случае undefined. Написание без скобок () позволяет поставить ССЫЛКУ на функцию: по клику выполни то, что написано в функции myFunck
} 

//Итого: одна функция на все три кнопки.

/********** ДРУГОЙ ПОДХОД *********/
//Допустим, у вас генерируются тов ары на сервере и они появляются в верстке: название и кнопка. А мы повесили события только на три конпки, которые уже есть. Как быть с новыми кнопками?.
//Выход: ставить событие на родителя товаров т.е. на div с классом wrap - мы ловим событие на ВСПЛЫТИИ:

document.querySelector('.wrap').addEventListener('click', event => {
//Если клик был совершен не по кнопке, то ничего не происходит
	if (event.target.tagName !== 'BUTTON') {
  	return;
  }
  //Получаем цену товара и выводим в консоль
  const price = event.target.dataset.price; //event.target - в данном случае это кнопка т.к. в if мы отсеяли все другие варианты и тэги, по которым пользователь может кликунть. У кнопки мы в data-атрибуте price вытащили цену товара и потом вывели ее в консоль:
  console.log(`Стоимость товара по данной кнопке: ${price}`);
});


//Еще один вариант румной работы с событиями, когда мы вешаем обработчик не на каждую кнопку, а на родительский блок, а уже условием проверяем куда прошел клилк. И если событие прошло не по кнопке - то ничего не произойдет. (см. Урок 4 - Шашков - ПРодвинутый JS - 21...