Нативні еквіваленти jQuery методів – Частина 3: Обробники подій
Це третина постів, присвячена нативним еквівалентам jQuery методів. Ви можете почитати Частина 1: Вибір DOM елементів, Частина 2: Робота з атрибутами та властивостями і Частина 4: Створення, вставка, переміщення та видалення елементів перш ніж продовжити.
Сьогодні ми розглядатимемо обробники подій.
Додавання оброблювача подій
jQuery
$(target).on(type, handler);
Нативний JS
target.ontype = handler
// or
target.addEventListener(type, handler);
Додавання обробника події click буде виглядати так:
jQuery
$(target).on('click', function(e) {
// do something when $(target) is clicked
});
Нативний JS
target.onclick = function(e) {
// do something when target is clicked
}
// or
target.addEventListener('click', function(e) {
// do something when target is clicked
});
Який із них використовувати?
Хоча обидва записи правильні, старий метод onevent
не бажано застосовувати у наш час, використовуйте addEventListener
метод.
Чому addEventListener?
Подивимося на наступне:
myElem.onclick = function(e) {
alert('A');
}
Натискання миші по myElem
показуватиме повідомлення з текстом ‘А’. Але якщо вам потрібно додати ще обробник події кліка миші?
Давайте спробуємо:
myElem.onclick = function(e) {
alert('B');
}
Клацніть миші по myElem
тепер показуватиме повідомлення з текстом ‘B’.
Що відбувається щоразу, додаючи обробник події, таким чином ви перезаписуєте(перевизначаєте) onclick
властивість myElem
, отже, незалежно від обробника визначеного раніше він пропадає і замінюється на поточний.
Метод addEventListener
дозволяє підключати на багато більше обробників до мети, якщо ви хочете. Якщо ми застосуємо метод addEventListener
у попередньому прикладі, то отримаємо 2 вікна повідомлення показуючи ‘A’ та ‘B’ відповідно – попередні обробники не будуть перезаписані!
Робочий приклад можна знайти тут.
Як і jQuery on()
метод, addEventListener
реєструє обробник на вказаному EventTarget
(елемент, document, window, і т.д.) і приймає обробник як другий параметр:
target.addEventListener(type, handler, useCapture);
type
– тип події (click, mouseover, change і т.д.)handler
– функція користувача викликається, коли вказана подія виникаєuseCapture
– булеве значення, не обов’язкове, краще вказувати як false (брехня)
Обговорення щодо способів застосування useCapture
(захоплення, спливання і т.д.) виходить за рамки цього посту, але гарний опис можна знайти тут.
Короткий запис
jQuery on()
може бути скорочено так:
$(target).on('click', handler);
// or
$(target).click(handler);
На жаль, немає рідного короткого методу для addEventListener
.
Інші приклади
jQuery
$(target).on('mouseover', function(e) {
// do something when a user hovers over $(target)
});
$(target).on('change', function(e) {
// do something when the change event fires
});
Нативний JS
target.addEventListener('mouseover', function(e) {
// do something when a user hovers over target
}, false);
target.addEventListener('change', function(e) {
// do something when the change event fires
}, false);
Як ви помітили, рідні методи дуже схожі на jQuery методи, але пам’ятайте, якщо $(target)
являє собою колекцію, то обробник подій застосовується до всіх елементів цієї колекції, але нативний метод не працюватиме на NodeList
повертається querySelectorAll
, getElementsByClassName
і т.д.
Ви можете пройти циклом за списком і додати обробники події для окремих вузлів (наприклад, додавання атрибутів або зміна класів):
var buttons = document.querySelectorAll('button');
// Loop over the buttons and add an event listener to each one
for ( var i = 0, len = buttons.length; i < len; i++ ) [
buttons[i].addEventListener('click' myListener, false);
}
Цей метод є досить громіздким і має велику кількість підводного каміння. Уявіть, до 300 елементів потрібно додати обробник – це створення 300 окремих обробників. А як щодо динамічного списку? При видаленні елемента також видаляємо обробник подій, кожному новому елементу додаємо.
Такі проблеми вирішується з допомогою “делегації подій”.
Нагадаю, що основна увага в цій серії постів полягає в наданні довідкового керівництва, щоб допомогти jQuery розробникам перейти на нативні методи. Піст про делегування подій стане непотрібним. Тим не менш, це важлива тема і будь-який JavaScript розробник повинен знати і на щастя вже є дивовижний пост, що охоплює його: Розуміння делегування подій JavaScript.
Видалення обробника події
jQuery
$(target).off(type, handler)
Нативний JS
target.removeEventListener(type, handler)
Зверніть увагу, якщо обробником є анонімна функція, то метод removeEventListener
не буде працювати.
Анонімна функція
target.addEventListener('click', function(e) {
alert("Hello, world");
}, false);
target.removeEventListener('click', function(e) {
alert("Hello, world");
});
Це не буде працювати, і target
буде, як і раніше, виводити “Hello, World” при натисканні.
Правильний метод:
Іменована функція
function myHandler() {
alert("Hello, world");
}
// add
target.addEventListener('click', myHandler, false);
// remove
target.removeEventListener('click', myHandler);
Одноразові події
jQuery
$(target).one('click', function(e) {
// do something once
});
І хоча немає нативної альтернативи методу one()
, нагадаю, що це просто скорочення для нього:
$(target).on(type, function(e) {
$(this).off(e);
// do something once
});
Ви вже вивчили еквіваленти для on()
і off()
методів, він повинен бути простим, щоб створити нативну версію one()
методу:
Нативний JS
target.addEventListener('click', function(e) {
this.removeEventListener(e.type, arguments.callee);
// do something once
}, false);
Document ready
jQuery
$(document).ready(function() {
// do stuff after page has fully loaded
});
// or simply
$(function() {
// do stuff after page has fully loaded
});
Нативний JS
document.addEventListener('DOMContentLoaded', function() {
// do stuff after page has fully loaded
});
Підтримка старих браузерів
Метод addEventListener
підтримується тільки в IE 9+, для IE 6+ потрібний метод attachEvent
. Швидкий крос-браузерний поліфіл:
function addListener(elem, event, fn) {
// check for addEventListener
if (elem.addEventListener) {
elem.addEventListener(event, fn, false);
} else {
elem.attachEvent("on" + event, function() {
return(fn.call(elem, window.event));
});
}
}
Застосування
addListener(elem, 'click', function(e) {
// do something when elem is clicked
});
Хоча спосіб вище застосовується тільки на додавання обробників подій, є безліч інших ресурсів і поліфілів які можуть більше.
Додатково прочитати: Events, addEventListener, removeEventListener, attachEvent
Настройтесь наступного разу, де ми розглянемо маніпуляції з DOM деревом.