Всплытие и обработка событий
Вызов большинства JavaScript-событий можно эмулировать непосредственно из самого скрипта. Вот есть у нас страничка лишь с одной ссылкой:
Мы можем «кликнуть» по ней используя одноимённый метод «.click()».:
$("a").get(0).click()
Обратите внимание на то, что я вызываю метод клик не у jQuery-объекта, а непосрдественно у DOM-элемента. Если же мы будем использовать jQuery-методы «.click()» или «.trigger()», то не получим результата:
$("a").click()
$("a").trigger("click")
Это объясняется тем, что они не запускают действие браузера по умолчанию, а лишь вызывают обработчики событий. Вернитесь к данному коду, когда добавите обработчики событий, он уже будет работать.
Таким образом мы можем притвориться пользователем, но этого недостаточно для работы. Нам надо научиться отслеживать поведение пользователя и своевременно реагировать на его действия. Начнём с начала, возьмём ссылку и добавим к ней простейший обработчик события click
:
$("a").on("click", function(event) {
alert("Hello!")
})
Для самых ходовых событий существуют «shorthand» методы, так, для отслеживания
click
используется «.click()», дляhover
— «.hover()» и так далее :) Во всех последующих примерах я будут использовать метод «.click()»
Теперь, кликнув по ссылке, вы увидите приветствие, и после закрытия оного браузер перейдет по ссылке, указанной в атрибуте «href».
— Только закрыл, хватит уже!
Да, это не совсем то, что мне хотелось – надо было лишь вывести текст и никуда не уходить. Ага, для этого стоит отменить действие по умолчанию:
$("a").click(function(event) {
alert("Hello!");
event.preventDefault();
})
Теперь перехода нет, т.к. метод «event.preventDefault()» предотвращает данное действие. Но вот если кто-то повесит ещё один обработчик на родительский элемент?
$("article").click(function(event) {
alert("Article!");
})
В результате мы получим два сообщения, но почему? Если у вас возникает подобный вопрос, значит, вы ещё не знакомы с тем, как обрабатываются события. Попробую кратенько дать вводную. Когда вы кликаете на элементе в DOM-дереве, то происходит «погружение» события – т.е. вначале все родительские элементы могут обработать «клик», и лишь потом он доберётся до элемента, по которому был совершён. Но и это ещё не всё. Затем событие начинает проделывать обратный путь – «всплывает», давая тем самым второй шанс родительским элементам обработать событие.
Но не так всё гладко — у нас же есть «бессмертный» IE, который принципиально не работает с «погружением», поэтому все решили идти по пути наименьшего сопротивления и обрабатывают события лишь на этапе «всплытия».
Рекомендую к прочтению статью «Всплытие и перехват» из уже упомянутого учебника Кантора.
Хорошо, вроде бы понятно, теперь вернёмся к нашему примеру, и попытаемся понять что же у нас происходит. Есть обработчик клика на ссылку и обработчик для меню с этой ссылкой. При клике на ссылку срабатывает обработчик события на ссылке, и затем событие всплывает до меню, и срабатывает его обработчик события «click». Но это не совсем желаемый результат, и для борьбы с подобным вредительством необходимо останавливать «всплытие» событий:
$("a").click(function(event) {
alert("Hello!");
event.preventDefault();
event.stopPropagation();
})
Для ускорения разработки в jQuery есть быстрый способ вызова этих двух методов за раз:
$("a").click(function(event) {
return false; // вот это он :)
})
Теперь у вас есть достаточный багаж знаний, чтобы легко манипулировать событиями на странице. Хотя я добавлю ещё немного — для того, чтобы сработал лишь ваш обработчик события, можно использовать метод «event.stopImmediatePropagation()»:
$("a").click(function(event) { // ваш обработчик события
alert("Hello!"); // он избранный
event.stopImmediatePropagation(); // он должен остаться только один
return false;
})
$("a").click(function(event) { // а это чужой обработчик событий
alert("Hello again!"); // он делает всё неправильно
return false;
})
В данном примере при клике на ссылке будет выведено лишь одно сообщение. И да, порядок имеет значение.