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

Вызов большинства 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;
})

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

results matching ""

    No results matching ""