Метод .on() присоединяет обработчики событий к текущему набору выбранных элементов в объекте jQuery. Начиная с jQuery 1.7, метод .on() предоставляет все необходимые функции для присоединения обработчиков событий. Для получения помощи в преобразовании из более старых методов событий jQuery, см. .bind(), .delegate() и .live(). Чтобы удалить привязанные события с помощью .on(), см. .off(). Чтобы присоединить событие, которое выполняется только один раз, а затем удаляет себя, см. .one()
Имена событий и пространства имён
Для аргумента events можно использовать любые имена событий. jQuery будет пропускать стандартные типы событий JavaScript браузера, вызывая функцию handler при генерации браузером событий из-за действий пользователя, таких как click. Кроме того, метод .trigger() может вызывать как стандартные имена событий браузера, так и пользовательские имена событий для вызова привязанных обработчиков. Имена событий должны содержать только буквенно-цифровые символы, знак подчеркивания и двоеточие.
Имя события может быть квалифицировано пространствами имён событий, которые упрощают удаление или вызов события. Например, "click.myPlugin.simple" определяет пространства имён myPlugin и simple для этого конкретного события click. Обработчик события click, привязанный с помощью этой строки, может быть удалён с помощью .off("click.myPlugin") или .off("click.simple") без нарушения других обработчиков click, привязанных к элементам. Пространства имён похожи на CSS-классы, так как они не являются иерархическими; достаточно совпадения только одного имени. Пространства имён должны содержать только буквы, цифры и символы нижнего регистра.
Во второй форме .on(), аргумент events представляет собой обычный объект. Ключи — это строки в том же формате, что и аргумент events с разделителями пробелов типов событий и необязательными пространствами имён. Значение для каждого ключа — это функция (или значение false ), которая используется в качестве handler вместо конечного аргумента метода. В других отношениях обе формы идентичны по своему поведению, как описано ниже.
Прямые и делегированные обработчики событий
Большинство событий браузера распространяются или пропагируются от самого глубокого, внутреннего элемента (целевой элемент события) в документе, где они происходят, до тела и элемента document. В Internet Explorer 8 и ниже некоторые события, такие как change и submit изначально не распространяются, но jQuery исправляет это, чтобы они распространялись и обеспечивали согласованное поведение в разных браузерах.
Если selector опущено или равно null, обработчик событий называется прямым или прямо связанным. Обработчик вызывается каждый раз, когда событие происходит на выбранных элементах, независимо от того, происходит ли оно непосредственно на элементе или распространяется от дочернего (внутреннего) элемента.
Когда указан selector, обработчик событий называется делегированным. Обработчик не вызывается, когда событие происходит непосредственно на связанном элементе, а только для дочерних (внутренних элементов), которые соответствуют селектору. jQuery распространяет событие от целевого элемента события до элемента, где обработчик прикреплен (т.е., от внутреннего к внешнему элементу), и запускает обработчик для всех элементов по этому пути, соответствующих селектору.
Обработчики событий привязываются только к текущим выбранным элементам; они должны существовать в момент вызова вами кода к .on(). Чтобы убедиться, что элементы присутствуют и могут быть выбраны, поместите скрипты после элементов в разметке HTML или выполните привязку событий внутри обработчика готовности документа. В качестве альтернативы используйте делегированные обработчики событий.
Делегированные обработчики событий имеют преимущество в том, что они могут обрабатывать события от дочерних элементов, которые добавляются в документ в более позднее время. Выбрав элемент, который гарантированно присутствует в момент привязки делегированного обработчика событий, вы можете использовать делегированные обработчики событий, чтобы избежать необходимости часто привязывать и удалять обработчики событий. Например, этот элемент может быть контейнерным элементом представления в проекте с архитектурой «Модель-Представление-Контроллер» или document если обработчик событий хочет отслеживать все события распространения в документе. Элемент document доступен в head документа до загрузки любого другого HTML, поэтому его безопасно прикрепить к нему события без ожидания готовности документа.
В дополнение к возможности обрабатывать события на дочерних элементах, которые еще не созданы, ещё одним преимуществом делегированных обработчиков событий является их потенциально низкая нагрузка при необходимости отслеживания многих элементов. В случае таблицы данных с 1000 строками в её tbody, этот пример привязывает обработчик к 1000 элементам:
$( "#dataTable tbody tr" ).on( "click", function() {
console.log( $( this ).text() );
}); Подход к делегированию событий привязывает обработчик событий только к одному элементу, tbody, и событие нужно распространить только на один уровень (от нажатого tr до tbody):
$( "#dataTable tbody" ).on( "click", "tr", function() {
console.log( $( this ).text() );
}); Примечание: Делегированные обработчики событий не работают для SVG.
Обработчик событий и его среда
Аргумент handler — это функция (или значение false, см. ниже), и он требуется, если вы не передаёте объект для аргумента events. Вы можете указать анонимную функцию обработчика в момент вызова .on(), как это сделано в примерах выше, или объявить именованную функцию и передать её имя:
function notify() {
alert( "clicked" );
}
$( "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 по адресу https://www.w3.org/TR/DOM-Level-3-Events/#event-types-list.
Возврат значения false из обработчика событий автоматически вызовет event.stopPropagation() и event.preventDefault(). Значение false также можно передать для аргумента handler в качестве сокращения для function(){ return false; }. Таким образом, $( "a.disabled" ).on( "click", false ); привязывает обработчик событий ко всем ссылкам с классом «disabled», который предотвращает переходы по ним при нажатии и также останавливает распространение события.
Когда jQuery вызывает обработчик, ключевое слово this ссылается на элемент, которому передаётся событие; для прямо связанных событий это элемент, к которому было прикреплено событие, а для делегированных событий — элемент, соответствующий selector. (Обратите внимание, что this может не совпадать с event.target, если событие распространилось от дочернего элемента.) Чтобы создать объект jQuery из элемента, который можно использовать с методами jQuery, используйте $( this ).
Передача данных в обработчик
Если аргумент data предоставляется методу .on() и не является null или undefined, он передаётся обработчику в свойстве event.data каждый раз при срабатывании события. Аргумент data может быть любого типа, но если используется строка, то selector должен быть предоставлен или явно передан как 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, переданному методу .on(), вы также можете передать данные в обработчик событий, используя второй аргумент для .trigger() или .triggerHandler(). Переданные таким образом данные передаются обработчику событий в качестве дополнительных параметров после объекта Event. Если в качестве второго аргумента для .trigger() или .triggerHandler() был передан массив, каждый элемент массива будет представлен обработчику событий в качестве отдельного параметра.
В большинстве случаев событие, такое как click, происходит редко, и производительность не является существенным фактором. Однако события высокой частоты, такие как mousemove или scroll, могут срабатывать десятки раз в секунду, и в этих случаях становится важнее использовать события обдуманно. Производительность можно повысить, уменьшив объем работы в самом обработчике, кешируя информацию, необходимую обработчику, вместо её перерасчёта или ограничив частоту обновления страницы с помощью setTimeout.
Прикрепление множества делегированных обработчиков событий в верхней части дерева документа может снизить производительность. Каждый раз, когда событие происходит, jQuery должен сравнивать все селекторы всех прикрепленных событий этого типа со всеми элементами на пути от целевого элемента события до верха документа. Для лучшей производительности прикрепляйте делегированные события в месте документа, как можно ближе к целевым элементам. Избегайте чрезмерного использования document или document.body для делегированных событий в больших документах.