Объект события
На стене музея одна табличка. Внешний ящик — #wall. Внутри #plaque держит ссылку #seal. На ссылке слово open, а href равен /wing. Под стеной #slip говорит blank.
Браузер передаёт функции один объект. Параметр зовут event. event.type — вид события. Клик ставит эту строку в click. event.target — элемент, на который сел клик. event.currentTarget — элемент, на котором сидит этот слушатель. Они совпадают, только если клик и слушатель на одном элементе.
Печать — ссылка. preventDefault отменяет переход на /wing. После вызова event.defaultPrevented равен true. Без вызова флаг остаётся false. Дальше клик идёт наружу: печать, табличка, стена. stopPropagation на табличке обрывает путь, слушатель стены не выполняется.
Скрипт страницы щёлкает печать один раз. Строка под табличкой: click / seal / plaque / true / quiet. Здесь не пишут onclick, не вызывают removeEventListener и не создают элемент.
Объект, который передаёт браузер
Прошлая страница была вешалка. У wool и silk не было параметра, они не читали этот объект. Их строка была wool silk / 2 / peg. Страница звонка записывала onclick и читала this. Эта страница так не делает. getElementById даёт только стену, табличку, печать и лист.
addEventListener по-прежнему только хранит функцию. Объект приходит, когда клик выполняет функцию, а не в момент добавления. currentTarget читай внутри функции. После возврата это свойство равно null.
Что сообщает один клик
Лист начинается с blank. Текст ссылки остаётся open. Читай строки по порядку. Каждый фрагмент начинается с этой свежей стены, кроме строки страницы: это демо внизу. Демо не вызывает removeEventListener.
📊 Что сообщает один клик
| Момент | Что читаешь | Текст листа | Легко перепутать |
|---|---|---|---|
слушатель на печати, seal.click(), чтение типа |
event.type |
click | читать id как тип |
| слушатель на табличке, клик по печати, target | event.target.id |
seal | читать currentTarget |
| тот же клик, currentTarget | event.currentTarget.id |
plaque | читать target |
preventDefault на печати, затем флаг |
event.defaultPrevented |
true | думать, что ссылка всё ещё уходит |
без preventDefault |
event.defaultPrevented |
false | думать, что каждый слушатель отменяет ссылку |
stopPropagation на табличке, стена тоже слушает |
склейка marks | plaque | ждать plaque wall |
скрипт страницы, один click |
строка | click / seal / plaque / true / quiet | строка кончается на wall |
Клик по печати — один объект. Все слушатели на пути видят его. type не меняется. target не меняется. currentTarget меняется: это элемент, чей слушатель сейчас выполняется.
preventDefault говорит со стандартным действием браузера. У этой ссылки действие — переход на /wing. Вызов не снимает слушателя со списка. stopPropagation говорит с путём. Ссылку он не отменяет. Вызов одного — не вызов другого.
join(" ") ставит пробел только между словами, которые уже лежат в marks. Пустой список здесь не склеивают. Лист начинается со слова blank и меняется только внутри слушателя или в скрипте страницы после клика.
Тип
Слушатель сидит на печати. Функция называет параметр event и пишет event.type на лист. Затем выполняется seal.click().
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
function readType(event) {
slip.textContent = event.type;
}
seal.addEventListener("click", readType);
seal.click();
console.log(slip.textContent);
Вывод — click. Тип — это вид события, не id и не слово open.
Элемент под кликом
Свежая стена. Слушатель на табличке, не на печати. Клик всё равно садится на печать. event.target — этот элемент, значит event.target.id равен seal.
let plaque = document.getElementById("plaque");
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
function readTarget(event) {
slip.textContent = event.target.id;
}
plaque.addEventListener("click", readTarget);
seal.click();
console.log(slip.textContent);
Вывод — seal. Элемент слушателя — табличка. target табличку не называет. Он называет элемент под кликом.
Где сидит слушатель
Та же свежая стена, слушатель всё ещё на табличке, клик всё ещё по печати. Лист пишет оба id: сначала target, потом currentTarget.
let plaque = document.getElementById("plaque");
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
function readWhere(event) {
slip.textContent = event.target.id + " " + event.currentTarget.id;
}
plaque.addEventListener("click", readWhere);
seal.click();
console.log(slip.textContent);
Вывод — seal plaque. Первое слово — клик. Второе — элемент, которому принадлежит этот слушатель. Повесь слушатель на печать и кликни печать: оба id будут seal, потому что клик и слушатель на одном элементе. Это чтение идёт с таблички, поэтому id разные. currentTarget читай внутри функции. После возврата он null.
Отменить ссылку
href печати — /wing. Стандартное действие этого клика — перейти по ссылке. preventDefault отменяет это действие. Слушателя он не снимает. Сразу после вызова event.defaultPrevented равен true.
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
function hold(event) {
event.preventDefault();
slip.textContent = String(event.defaultPrevented);
}
seal.addEventListener("click", hold);
seal.click();
console.log(slip.textContent);
Вывод — true. Без preventDefault то же чтение даёт false. Лист скажет false, и действие ссылки останется. stopPropagation этот флаг не ставит.
Клик идёт наружу
Печать внутри таблички, табличка внутри стены. Клик по печати доходит до слушателя таблички, затем до слушателя стены, если путь не оборван. stopPropagation на табличке обрывает его. Функция стены не выполняется. preventDefault путь не обрывает.
let wall = document.getElementById("wall");
let plaque = document.getElementById("plaque");
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
let marks = [];
function onPlaque(event) {
marks.push("plaque");
event.stopPropagation();
}
function onWall() {
marks.push("wall");
}
plaque.addEventListener("click", onPlaque);
wall.addEventListener("click", onWall);
seal.click();
slip.textContent = marks.join(" ");
console.log(slip.textContent);
Вывод — plaque. Слово wall в marks не попадает. Без stopPropagation тот же клик записал бы plaque wall. Демо внизу и обрывает путь, и отменяет ссылку.
Одна строка под табличкой
Скрипт стоит в конце body, когда стена и абзацы уже есть. Слушатель печати вызывает preventDefault. Слушатель таблички вызывает stopPropagation и запоминает тип, id у target, id у currentTarget и флаг. Слушатель стены поставил бы heard в wall, но путь уже оборван, поэтому heard остаётся quiet. Строка пишется после seal.click(), когда у стены был шанс.
<!DOCTYPE html>
<html>
<head>
<title>event-object — page</title>
</head>
<body>
<div id="wall">
<div id="plaque">
<a id="seal" href="/wing">open</a>
</div>
</div>
<p id="slip">blank</p>
<p id="line">…</p>
<script>
let wall = document.getElementById("wall");
let plaque = document.getElementById("plaque");
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
let kind = "";
let from = "";
let on = "";
let held = "";
let heard = "quiet";
seal.addEventListener("click", function (event) {
event.preventDefault();
});
plaque.addEventListener("click", function (event) {
event.stopPropagation();
kind = event.type;
from = event.target.id;
on = event.currentTarget.id;
held = String(event.defaultPrevented);
});
wall.addEventListener("click", function () {
heard = "wall";
});
seal.click();
slip.textContent = kind + " " + from + " " + on;
document.getElementById("line").textContent =
kind + " / " + from + " / " + on + " / " + held + " / " + heard;
</script>
</body>
</html>
Строка читается click / seal / plaque / true / quiet. Тип — click. id у target — seal. id у currentTarget — plaque, потому что этот слушатель на табличке. Флаг true, потому что слушатель печати вызвал preventDefault раньше, чем табличка прочитала флаг. Последнее слово quiet, не wall, потому что stopPropagation сработал на табличке. Текст open в строку не входит. Лист становится click seal plaque. Следующая страница — делегирование. Печать уже есть в разметке. Здесь после слушателя ребёнка не добавляют.
Пять проверок у таблички
- Повесь слушатель на печать и кликни. Лист — click.
- Повесь слушатель на табличку, кликни печать и прочитай
event.target.id. Лист — seal. - Тот же слушатель пишет оба id. Лист — seal plaque. Слушатель на самой печати написал бы seal seal.
- Вызови
preventDefaultи прочитайevent.defaultPrevented. Лист — true. Без вызова — false. - Вызови
stopPropagationна табличке, стена тоже слушает. marks склеивается в plaque. Прочитай строку: click / seal / plaque / true / quiet.
Где эта табличка обманывает
На ссылке по-прежнему open. Лист — не текст ссылки.
- Ждать, что аргумент функции — элемент печати, а не объект события
- Читать
event.target, когда нужен элемент слушателя - Читать
event.currentTarget, когда нужен элемент под кликом - Ждать, что
preventDefaultснимет слушателя, какremoveEventListenerна вешалке - Ждать, что
stopPropagationотменит переход на/wing - Ждать, что слушатель стены выполнится после
stopPropagationна табличке - Читать
event.currentTargetпосле возврата функции и ждать plaque - Писать
onclickили читатьthisиtypeof null; это была страница звонка - Собирать ссылку через
createElement; это была более ранняя страница - Читать строку так, будто она кончается на wall, или как wool silk / 2 / peg
Что остаётся
- После клика
event.typeравен click - Слушатель на табличке и клик по печати:
event.target.idравен seal - На том же клике
event.currentTarget.idравен plaque - Слушатель на печати: target и currentTarget оба равны seal
preventDefaultделаетevent.defaultPreventedравным true, без вызова остаётся falsestopPropagationна табличке не даёт выполниться слушателю стены- Строка страницы: click / seal / plaque / true / quiet
🧠 Проверьте Свои Знания
Проверьте Свои Знания
Бросьте себе вызов с помощью этой интерактивной викторины и узнайте, насколько хорошо вы понимаете тему
📝 Инструкции
- Внимательно прочитайте каждый вопрос
- Выберите лучший ответ на каждый вопрос
- Вы можете пересдавать тест столько раз, сколько захотите
- Ваш прогресс будет показан вверху