Уроки JavaScript – Об’єкт події (Event Object)
В попередній статті ми розглянули основні події в браузері. Сьогодні ми розширимо цю тему, та коротко розглянемо Об’єкт події (Event Object), який є одним з важливих аспектів обробки подій.
Всякий раз, коли ви прив’язуєте функцію до події, тобто коли ви створюєте обробник подій, функція буде передана об’єкту. Це трапляється на самому початку, тому нам не потрібно робити для цього додаткових кроків. Цей об’єкт події містить різноманітну інформацію про подію, яка тільки що відбулася; він також містить виконувані методи, які мають різні поведінкові ефекти на подію.
Відмітьте, що IE браузери не передають цей об’єкт події, замість цього ви повинні отримати доступ до неї як властивості глобального об’єкта window
:
function firstEventHandler (e) { // зверніть увагу на аргумент "e" // коли ця функція викликається в результаті здійснення події, буде передано об'єкт події // робимо "e" крос-браузерним: e = e || window.event; // тепер можна спокійно посилатися на 'e' у всіх сучасних браузерах } // зв'язуємо нашу функцію з подією тут ...
Для того, щоб перевірити наявність об’єкта “e
” (Об’єкт події), ми використовуємо логічний оператор OR
(АБО), який в основному перевіряє наступне: якщо e
є “хибним” значенням (null
, undefined
, 0
і т.д.), для e
привласнити window.event
; інакше використовується e
. Це швидкий і простий спосіб отримати реальний об’єкт події в крос-браузерному середовищі. Якщо вам не до вподоби використання логічних операторів, ви можете використовувати умовний оператор IF
:
if (!e) { e = window.event; } // тут не потрібна ELSE умова, оскільки "e" вже буде визначено в інших браузерах
Деякі з найбільш корисних команд і властивостей цього об’єкта події, на жаль, неузгоджені в різних браузерах (а саме IE тут найбільше виділяється). Наприклад, скасування дії за замовчуванням події може бути досягнуто за допомогою методу preventDefault()
Об’єкта події, але в IE це може бути досягнуто тільки за допомогою властивості returnValue
об’єкта. Отже, знову ж таки, ми повинні використовувати обидва варіанти, щоб охопити практично всі браузери:
function firstEventHandler(e) { e = e || window.event; // відміняємо дефолтну (за замовчуванням) дію для події: if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; } }
Дефолтною дією події є те, що зазвичай відбувається в результаті здійснення події. Коли ви натискаєте на лінк, за замовчуванням браузер переходить до адреси, що вказана в атрибуті “href
” цього посилання. Але іноді потрібно вимкнути цю дію за замовчуванням.
Розбіжності між returnValue
та preventDefault
, інші невдалі реалізації властивостей Об’єкта події вимагають обов’язкового використання конструкцій типу if else
.
Багато популярних JavaScript бібліотек нормалізують об’єкт події, тобто команди, такі як e.preventDefault
, будуть доступні в IE, хоча слід пам’ятати, що інколи властивість returnValue
все ще використовується.
Розповсюдження події
Розповсюдження подій – це коли подія відбулась, а потім вона зачіпає весь DOM знизу догори. Перше, що потрібно відзначити, — не всі події мають такий ефект, але якщо вони його мають, то це виглядає приблизно так:
- Подія запускається на цільовому елементі. Потім подія спрацьовує на кожному предкові цього елемента – подія проходить через весь DOM, поки не досягне верхнього елемента, наприклад:
- Відбулась подія click на тегові
<a>
- Відбулась подія click на тегові
<p>
- Відбулась подія click на тегові
<div>
- Відбулась подія click на тегові
<body>
- Відбулась подія click на тегові
- Ці події будуть спрацьовувати в такому порядку, вони не відбуваються всі одночасно.
Ця поведінка може бути припинена в будь-який час процесу. Якщо вам потрібно, щоб подія стосувалася абзацу (тегу <p>
), але не просувалася далі (до вузла <body>
), ви можете скористатися іншим корисним методом, що міститься у Об’єкті події, stopPropagation
:
function firstParagraphEventHandler(e) { e = e || window.event; // перериваємо розповсюдження події: if(e.stopPropagation) { e.stopPropagation(); } else { e.cancelBubble = true; // IE } } // функція буде пов'язана з подією click, використовуючи нашу спеціальну функцію addEvent: addEvent( document.getElementsByTagName('p')[0], 'click', firstParagraphEventHandler );
Делегування події
Припустімо, що у вас є велика таблиця з безліччю рядків даних. Прив’язка обробника подій click
до кожного окремого елементу <tr>
може мати погані наслідки, та буде негативно впливати на продуктивність. Найпоширенішим способом боротьби з цією проблемою є використання “делегування подій”. Делегування подій описує процес застосування обробника подій до елемента контейнера, а потім використовує його як основу для всіх дочірніх елементів. Тестуючи властивість target
(srcElement
в IE) Об’єкта події, ми можемо визначити реальний елемент, який було натиснуто.
var firstTable = document.getElementById('big-table'); firstTable.onclick = function() { // турбуємось про сумісність в браузерах: e = e || window.event; var targetNode = e.target || e.srcElement; // перевіряємо, чи був натиснутий тег TR: if ( targetNode.nodeName.toLowerCase() === 'tr' ) { alert ('Ви натиснули на рядку таблиці!'); } }
Делегування події покладається на розповсюдження подій. Наведений вище код не працюватиме, якщо розповсюдження події зупинилося до досягнення вузла <table>
.
Ось і все на сьогодні! Сподіваємось, що ви дізналися щось корисне сьогодні. В наступних уроках ми продовжимо детальне вивчення мови програмування JavaScript.