Прослуховувач подій addEventListener

Нехай по кліку на кнопку ми хочемо використати 2 обробника подій:

<button>test</button>

let button = document.querySelector('button');
button.onclick = function(){ this.innerText = 'Hello!'; };
button.onclick = function(){ console.log('click on button'); };

Друга функція просто затирає першу, і перша перестане виконуватися.

Для роботи з декількома однотипними подіями є спеціальний об'єкт - прослуховувальник подій: addEventListener.

element.addEventListener('event', handler);
button.addEventListener('click', function(){ this.innerText = 'Hello!'; }); button.addEventListener('click', function(){ console.log('click on button'); });

Зверніть увагу, що подія записується без букв on, і це - строковий аргумент, тобто, назва події може зберігатися у змінній:

let evname = a > b ? 'click' : 'mouseenter';
button.addEventListener(evname, function(){ console.log('hello'); });

Видалити подію можна методом .removeEventListener().

Видаляти події потрібно коли в них вже немає необхідності, а повторний виклик події може спричинити проблеми.

Уявіть ситуацію: ви зробили форму і програмну обробку даних цієї форми, відправку на сервер по кліку на кнопку. Якщо користувач двічі клацне по кнопці - дані двічі відправляться на сервер.

Щоб уникнути цього - при першому кліку подію обробки та відправки даних потрібно прибрати з кнопки.

function subm(){
  button.removeEventListener('click', subm);
  if (validateForm()) { form.submit(); }
}
button.addEventListener('click', subm);

Зверніть увагу, що для видалення функції потрібно використовувати ім'я функції, анонімні функції видаляти неможна.

Власні події і програмний виклик подій з прослуховувальника

Можна створювати власні події.

Нехай нам потрібна подія, що виникне через 2 секунди після натискання на кнопку. Напишемо обробник цієї події:

button.addEventListener('button2s', function(){ alert('ok'); });

Події можна називати довільно, як змінні, в даному випадку - button2s.

Для іменування подій в складних плагінах часто використовують простір імен. Наприклад, у бутстрапі події переключення табів мають такі назви:

show.bs.tab
shown.bs.tab
hide.bs.tab
hidden.bs.tab

Саму подію ініціюємо (викликаємо) методом dispatchEvent:

button.onclick = function(){
  setTimeout(function(){
    button.dispatchEvent(new Event('button2s'));
  }, 2000);
}

Подію можна підв'язати під будь-який об'єкт:

document.body.addEventListener('hey', function(){ ... });
window.addEventListener('hey', function(){ ... });
document.querySelector('h1').addEventListener...;

document.body.dispatchEvent(new Event('hey'));
window.dispatchEvent(new Event('hey'));
document.querySelector('h1').dispatchEvent...;

Тестове завдання

  1. Що робить наступний код? ...
    let lines, a = 'action';
    div['onmouse' + btn.dataset[a]] = function(){
      if (!(lines = document.forms[x].children).length){
        console.dir(lines);
        let y = document.forms[x].getAttribute(a);
        lines = getLines()[y](x);
      }
    }