Урок - Метод jQuery.on() - назначение обработчиков событий.

Главная » Курсы » Курс jQuery, Быстрый старт. (jQuery 1.10.2 / jQuery 2.0.3) » Урок - Метод jQuery.on() - назначение обработчиков событий.
Группа вКонтакте
Лицензия: Лицензия Creative Commons.

Метод jQuery.on() позволяет назначать обработчики для одного или нескольких событий, для выбранных элементов.

Синтаксис метода jQuery.on().

  • jQuery.on( events [, selector ] [, data], handler(eventObject) )
  • jQuery.on( eventsList [, selector ] [, data] )

где

  • events - строка, один или более (разделенные пробелом) типов событий и/или пространство имен. Например: "click", "click.myPlugin".
  • selector - строка, селектор, для фильтрации потомков выбранных элементов, для которых вызывается событие. Если селектор не указан или равен null, то событие всегда срабатывает при достижении выбранных элементов.
  • data - данные передаваемые в обработчик в переменную event.data когда выполняется событие.
  • handler(eventObject) - функция, обработчик вызываемая для события. Значение false является кратким аналогом для функции возвращающей return false.
  • eventsList - объект, где строковый ключ представляет один или более разделенных пробелом типов событий и/или пространство имен, а значение объекта представляет  обработчики ранее назначенные событию(-ям).

Синтаксис метода jQuery.on().

Метод jQuery.on() назначает обработчики событий для текущих выбранных элементов из jQuery-объекта. С версии jQuery 1.7 метод jQuery.on() обеспечивает необходимый функционал для назначения обработчиков событий. Для перехода со старых методов jQuery к новым смотрите документацию по методам jQuery.bind(), jQuery.delegate() и jQuery.live(). Для удаления обработчиков назначенных с помощью jQuery.on() смотрите документацию по методу jQuery.off(). Для назначения обработчиков разового выполнения смотрите метод jQuery.one().

Названия событий и пространства имен.

Любое имя события можно использовать в качестве аргумента events. jQuery будет просматривать все стандартные JavaScript-события браузера и вызывать функции-обработчики, когда браузер генерирует событие в связи с действиями пользователя, например щелчек мыши. Кроме того метод jQuery.trigger()  может вызывать как стандартные так и пользовательские события. Имена событий могут содержать только буквы латинского алфавита, цифры, подчеркивание и двоеточие.

Названия событий могут быть квалифицированы по событию пространства имен, которые упрощают удаление или инициорование событий. Например "click.myPlugin.simple" определяет для события click пространства имен myPlugin и simple. Обработчики назначенные этой строкой могут быть сняты командой jQuery.off('click.myPlugin') или jQuery.off('click.simple') не нарушая другие обработчики назначенные элементам. Пространства имен аналогичны CSS-классам в том. что они не являются иерархичными - должно совпадать только одно имя. пространства имен начинающиеся с символа подчеркивания зарезервиорваны в jQuery.

Во втором варианте синтаксиса метода jQuery.on() аргумент eventsList является простым объектом. Ключи - это строки такие же как и аргумент events в первом варианте синтаксиса метода jQuery.on(), т.е. название события с пространством имен. Значением для каждого ключа является функция (или специальное значение false), которая будет использоваться в качестве обработчика. В остальном эти два варианта синтаксиса идентичны по работе и их поведение описано ниже.

Прямые и делегированные события.

Большинство событий браузера как пузыри, распространяются от самого глубокого (внутреннего, целевого) элемента в документе, где произошло событие, и поднимаются вверх до элемента body и элемента документа. В Internet Explorer ниже 8-й версии некоторые события (например change, submit) не являются пузырьковыми, но это исправлено в jQuery для создания кроссбраузерности.

Если селектор опущен или null, обработчик событий называют прямым (directly) или связанным на прямую (directly-bound). Обработчик вызывается каждый раз, когда происходит событие, на выбранных элементах, происходит ли это непосредственно на элементе или пузырьки из потомков (внутренний) элемента.

Когда селектор указан, обработчик события называется делегированным (delegated). Обработчик не вызывается, когда событие происходит непосредственно на делегированном элементе, но только для потомков (внутренние элементы), которые соответствуют селектору. JQuery пузырьки события подымаются с целевого элемента до элемента, в котором вложен обработчик (т.е. от внутреннего к внешним элементам) и запускает обработчик для любых элементов по пути соответствия селектора.

Обработчики событий связан только с выбранными элементами; они должны существовать на странице во время вызова jQuery.on(). Для этого, присутствующие элементы в HTML могут быть выбраны и обработчики событий назначены в document ready. Если на страницу вставляется новый HTML-код, то назначение обработчиков событий необходимо выполнить по сле вставки нового HTML-кода в страницу. Или используйте делегированные события для назначения обработчиков событий, как описано ниже.

Делегированные события имеют то преимущество, что они могут обрабатывать события от элементов-потомков, которые добавляются к документу, в более позднее время. Выбрав элемент, который гарантированно будет присутствовать в будущем, делегировав вложеный обработчик событий, вы можете использовать делегированные события, чтобы избежать необходимости частого назначения и удаления обработчиков событий. Этот элемент может быть элементом-контейнером (например, для конструкции MVC (Model-View-Controller)) или документом (если обработчик события хочет контролировать все события всплывающие в документе). Элемент документа доступен в заголовке документа перед загрузкой любого другого HTML, так что это безопасный способ назначить события не дожидаясь готовности (ready) документа.

В дополнение к способности обрабатывать события от еще не созданных элементов-потомков, другим преимуществом делегированных событий является экономия нагрузки, когда должно контролироваться множество элементов. В таблице с 100 строк в TBODY, в примере присоединяется обработчик к 1000 элементам:

jQuery("#dataTable tbody tr").on("click", function(event){
    alert(jQuery(this).text());
});

В делегированных событияхобработчик присоединяется только к элементу TBODY и событию необходимо подняться только на один уровень вверх (от TR к TBODY):

jQuery("#dataTable tbody").on("click", "tr", function(event){
    alert(jQuery(this).text());
});

Обратите внимание: Делегированные события не работают с SVG.

Обработчик события и его окружение.

Аргумент handler это функция (или false, смотрите ниже) требуется, если вы не передали в качестве аргумента событие. Вы можете предоставить анонимную функцию обработчика в месте вызова jQuery.on(), как сделано выше, или объявить именную функцию и передать её имя:

function notify() {
    alert("clicked");
}
jQuery("button").on("click", notify);

Когда браузер инициирует событие или другой JavaScript вызывает метод JQuery.trigger(), Jquery передает обработчик события объекта, чтобы проанализировать и изменить статус события. Этот объект является нормализованным набором данных, предоставленных браузером; немодифицированном родной event-объект браузера доступен в event.originalEvent. Например, event.type содержит имя события (например, "resize"), а event.target указывает на целевой (внутренний) элемент, где произошло событие.

По умолчанию большинство событий всплывают от первоначального целевого элемента события к  элементу document. На каждый элемент по пути всплытия, jQuery вызывает все соответствующие обработчики событий, которые были назначены. Обработчик может предотвратить всплытие собятия далее вверх по дереву документов (и тем самым предотвратить выполнени обработчиков на родительских элементах), вызывая event.stopPropagation(). Любые другие обработчики, назначенные на текущем элемент будут выполнены. Чтобы не допустить этого, вызовите event.stopImmediatePropagation(). (Обработчики событий назначенные элементу вызывают в том же порядке, в котором они были назначены.)

Аналогичным образом, обработчик может вызвать event.preventDefault(), чтобы отменить действие бразуера по умолчанию, назначенное этому событию. Например, действия по умолчанию для события click у ссылки является переход к другому документу. Не на все события у браузера есть действия по умолчанию, и не все действия по умолчанию, могут быть отменены. Делати смотрите в W3C Events Specification.

Возвращаясь false из обработчика события автоматически приведет к вызову event.stopPropagation() и event.preventDefault(). Значение false также могут быть переданы для обработчика в качестве краткого обозначения кода

function() {
    return false;
}
Например:

jQuery("a.disabled").("click", false);

Пример выше назначает событий для всех ссылок с классом "disabled", что приводит к запрету всплытия события и запрету выполнения действия браузера по умолчанию.

Когда jQuery вызывает обработчик, это ключевое слово this является ссылкой на элемент, где возникло событие; для непосредственной связи событиями этого элемента, которому событие было назначено, а для делегированных событий this это элемент, соответствующий селектору. (Заметим, что this не может быть равна event.target если событие всплывает от потомка элемента.) Чтобы создать jQuery объект из элемента, для использования jQuery-методов, используйте jQuery(this).

Передача данных в обработчик.

Если указан аргумент data jQuery.on() и он не является null или undefined, данные передаются в обработчик в переменную event.data каждый раз при возникновении события. Аргумент data может быть любого типа, но если в строке используется селектор необходимо это указать или передать null что бы данные не воспринимались как селектор. Лучшая выход заключается в использовании простого объекта, чтобы несколько значения могли быть переданы как свойства.

Начиная с версии jQuery 1.4, один и тот же обработчик событий может быть назначен элементу несколько раз. Это особенно полезно, когда в функции используется event.data, или когда другие уникальные данные находятся в окружениифункции обработчика событий. Например:

function greet(event) {
    alert("Hello "+event.data.name);
}
$("button").on("click", { name: "Karl" }, greet);
$("button").on("click", { name: "Addy" }, greet);

Указанный код будет генерировать два разных предупреждения при нажатии кнопки.

В качестве альтернативы или в дополнение аргумент data метода jQuery.on() может использоваться в методах jQuery.trigger() или jQuery.triggerHandler().

Производительность событий.

В большинстве случаев, такое событие, как click происходит редко и производительность не является значительной проблемой. Тем не менее, высокая частота событий, таких как scroll (прокрутка) или mousemove (движение мыши) может выполняться десятки раз в секунду, в этих случаях, становится важным использовать события рассудительно. Производительность может быть увеличена за счет уменьшения количества работы, выполняемой в обработчике, кэширование информации, необходимой для обработчиков, а не пересчета, или на ограничение скорости фактического количества обновлений страницы с помощью SetTimeout.

Назначение большого количества делегированных обработчиков событий в верхней части дерева документа может снизить производительность. Каждый раз, когда происходит событие, jQuery должен сравнить все селекторы всех вложенных событий этого типа до каждого элемента в пути от целевого элемента события до верхней части документа. Для лучшей производительности, нужно назначать делегированое событие в документе расположеное как можно ближе к целевым элементам. Избегайте чрезмерного использования document или document.body для делегированных событий в больших документах.

jQuery может обрабатывать простые селекторы вида tag#id.class очень быстро, когда они используются для фильтрации делегированных событий. Итак, "#myForm", "a.external" и "button" это быстрые селекторы. Делегированные событий, которые используют более сложные селекторы, особенно иерархические, могут быть в несколько раз медленнее, - хотя они все еще достаточно быстро для большинства приложений. Иерархических селекторов часто можно избежать, просто назначая обработчика в более подходящем месте в документе. Например, вместо

jQuery("body").on("click", "#commentForm .addNew", AddComment)

используйте

jQuery("#commentForm").on("click", ".addNew", AddComment).

Дополнительные примечания.

в jQuery есть сокращенные методы для некоторых событий, таких как .click(), которые могут быть использованы для назначения или вызова обработчика событий. Для получения полного списка сокращенных методов см. в категории событий.

В jQuery 1.8 у
старел и удален в версии jQquery 1.9: Название "hover", используемое в качестве краткого обозначения строки "mouseenter mouseleave". Он давал возвожность назначать один обработчик событий для этих двух событий, но в обработчике необходимо проверить event.type чтобы определить, является ли событие mouseenter или mouseleave. Не путайте псевдо-событие "hover" имя с методом .hover(), который получает одну или две функции в качестве обработчиков..

Система событий jQuery требует, чтобы элемент DOM позволяли присоединять данных через свойство к элементам, так чтобы события могли быть отслежены и доставлены. Однако элементам object, embed и applet не возможно прикреплять данные, и, следовательно, не возможно связывать события с ними через jQuery.

События focus и blur, по стандарту W3C, не являются всплывающими, но jQuery определяет кросс-браузерные всплывающие события focusin и focusout. Когда используются focus и blur, для назначения делегированных обработчиков событий, jQuery изменяет их имена передает как focusin и focusout соответственно. Для согласованности и прозрачности, используйте всплывающие типы событий.

Во всех браузерах события load, scroll и error (например, для элемента <img>) не всплывающие. В Internet Explorer 8 и ниже, события paste и reset не всплывающие. Эти события не используются для делегирования, но они могут быть использованы, когда обработчик событий, непосредственно связанный с элементом генерирующим событие.

Событие error в объекте window использует нестандартные аргументы и конвенции возвращаемого значения - по этому событие не поддерживается в jQuery. Вместо этого назначьте свою функцию обработчика непосредственно к свойству window.onerror.

Примеры использования метода jQuery.on().

Пример 1: Отобразить текст параграфа в Alert-окне при клике.

jQuery("p").on("click", function(){
    alert( jQuery(this).text() );
});

Пример 2: Передать данные в обработчик.

function myHandler(event) {
    alert(event.data.foo);
}
jQuery("p").on("click", {foo: "bar"}, myHandler)

Пример 3: Отменить отправку данных формы и прекратить "всплытие" события вверх выполняя команду return false.

jQuery("form").on("submit", false)

Пример 4: Отменить действие по умолчанию для отправки формы используя preventDefault().

jQuery("form").on("submit", function(event) {
    event.preventDefault();
});

Пример 5: Отменить всплытие события вверх без отмены действия по умолчанию.

jQuery("form").on("submit", function(event) {
    event.stopPropagation();
});

Пример 6: Назначение и выполнение пользовательского (не браузерного) события.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        p { color:red; }
        span { color:blue; }
    </style>
    <script src="http://code.jquery.com/jquery-1.10.1.js"></script>
    <script>
        jQuery(function(){
            $("p").on("myCustomEvent", function(e, myName){ 
                $(this).text(myName + ", здесь!");
                $("span")
                    .stop()
                    .css("opacity", 1)
                    .text("myName = " + myName)
                    .fadeIn(30).fadeOut(1000)
                ;
            });
            $("button").click(function () {
                $("p").trigger("myCustomEvent", [ "Святогор" ]);
            });
        });
    </script>
</head>
<body>
    <p>Назначено пользовательское событие.</p>
    <button>Выполнить пользовательское событие</button>
    <span style="display:none;"></span>
</body>
</html>

Пример 7: Назначение нескольких обработчиков событий одновременно, используя просой объект.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        .test { color: #000; padding: .5em; border: 1px solid #444; }
        .active { color: #900;}
        .inside { background-color: aqua; }
    </style>
    <script src="http://code.jquery.com/jquery-1.10.1.js"></script>
    <script>
        jQuery(function(){
            $("div.test").on({
                click: function(){
                    $(this).toggleClass("active");
                },
                mouseenter: function(){
                    $(this).addClass("inside");
                },
                mouseleave: function(){
                    $(this).removeClass("inside");
                }
            });
        });
    </script>
</head>
<body>
    <div class="test">test div</div>
</body>
</html>

Пример 8: Назначаем обрабюотик для события click для всех параграфов. Щелкните на любой пункт, чтобы добавить еще один параграф. Обратите внимание, что метод jQuery.on() назначает обработчик не только для существующих элементов <p>, но и для вновь созданных.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        p { background:yellow; font-weight:bold; cursor:pointer;
        padding:5px; }
        p.over { background: #ccc; }
        span { color:red; }
    </style>
    <script src="http://code.jquery.com/jquery-1.10.1.js"></script>
    <script>
        jQuery(function(){
            var count = 0;
            $("body").on("click", "p", function(){
                $(this).after("<p>Новый параграф! "+(++count)+"</p>");
            });
        });
    </script>
</head>
<body>
    <p>Жми здесь!</p>
    <span></span>
</body>
</html>

Пример 9: Отобразить текст параграфа по которому кликнули в любое время создания элемента <p>.

jQuery("body").on("click", "p", function(){
    alert( $(this).text() );
});

Пример 10: Отменить действие по умолчанию для всех ссылок.

jQuery("body").on("click", "a", function(event){
    event.preventDefault();
});