Всплытие и обработка событий

Вызов большинства JavaScript-событий можно эмулировать непосредственно из самого скрипта. Вот есть у нас страничка лишь с одной ссылкой:

Мы можем «кликнуть» по ней используя одноимённый метод click():

$("a").get(0).click()

Обратите внимание на то, что я вызываю метод клик не у jQuery-объекта, а непосредственно у DOM-элемента. Если же мы будем использовать jQuery-методы click() или trigger(), то не получим результата:

Это объясняется тем, что они не запускают действие браузера по умолчанию, а лишь вызывают обработчики событий. Вернитесь к данному коду, когда добавите обработчики событий, он уже будет работать.

Таким образом мы можем притвориться пользователем, но этого недостаточно для работы. Нам надо научиться отслеживать поведение пользователя и своевременно реагировать на его действия. Начнём с начала, возьмём ссылку и добавим к ней простейший обработчик события click:

Для самых ходовых событий существуют «shorthand» методы, так, для отслеживания click используется click(), для hoverhover() и так далее :)

Во всех последующих примерах я будут использовать метод click()

Теперь, кликнув по ссылке, вы увидите приветствие, и после закрытия оного браузер перейдет по ссылке, указанной в атрибуте href.

— Только закрыл, хватит уже!

Да, это не совсем то, что мне хотелось – надо было лишь вывести текст и никуда не уходить. Ага, для этого стоит отменить действие по умолчанию:

Теперь перехода нет, т.к. метод event.preventDefault() предотвращает данное действие. Но вот если кто-то повесит ещё один обработчик на родительский элемент?

В результате мы получим два сообщения, но почему? Если у вас возникает подобный вопрос, значит, вы ещё не знакомы с тем, как обрабатываются события. Попробую кратенько дать вводную. Когда вы кликаете на элементе в DOM-дереве, то происходит «погружение» события – т.е. вначале все родительские элементы могут обработать «клик», и лишь потом он доберётся до элемента, по которому был совершён. Но и это ещё не всё. Затем событие начинает проделывать обратный путь – «всплывает», давая тем самым второй шанс родительским элементам обработать событие.

Но не так всё гладко — у нас же есть «бессмертный» IE, который принципиально не работает с «погружением», поэтому все решили идти по пути наименьшего сопротивления и обрабатывают события лишь на этапе «всплытия».

Рекомендую к прочтению статью «Всплытие и перехват» из уже упомянутого учебника Кантора.

Хорошо, вроде бы понятно, теперь вернёмся к нашему примеру, и попытаемся понять что же у нас происходит. Есть обработчик клика на ссылку и обработчик для меню с этой ссылкой. При клике на ссылку срабатывает обработчик события на ссылке, и затем событие всплывает до меню, и срабатывает его обработчик события «click». Но это не совсем желаемый результат, и для борьбы с подобным вредительством необходимо останавливать «всплытие» событий:

Для ускорения разработки в jQuery есть быстрый способ вызова этих двух методов за раз:

Теперь у вас есть достаточный багаж знаний, чтобы легко манипулировать событиями на странице. Хотя я добавлю ещё немного — для того, чтобы сработал лишь ваш обработчик события, можно использовать метод event.stopImmediatePropagation():

В данном примере при клике на ссылке будет выведено лишь одно сообщение. И да, порядок имеет значение.

Last updated