Spec-Zone.ru › jQuery

.on()

.on( events [, selector ] [, data ], handler )Возвращает: jQuery

Описание: Назначает функцию-обработчик одного или нескольких событий выбранным элементам.

  • добавлено в версии: 1.7.on( events [, selector ] [, data ], handler )

    • events
      Тип: String
      Один или несколько разделённых пробелами типов событий и необязательных пространств имён, например "click" или "keydown.myPlugin".
    • selector
      Тип: String
      Строка селектора для фильтрации потомков выбранных элементов, которые вызывают событие. Если значение selector равно null или параметр опущен, событие вызывается всегда, когда достигает выбранного элемента.
    • data
      Тип: Anything
      Данные, передаваемые обработчику в свойстве event.data при возникновении события.
    • handler
      Тип: Function( Event eventObject [, Anything extraParameter ] [, ... ] )
      Функция, выполняемая при возникновении события. Также допускается значение false — сокращённая запись функции, которая просто выполняет return false.
  • добавлено в версии: 1.7.on( events [, selector ] [, data ] )

    • events
      Тип: PlainObject
      Объект, в котором строковые ключи представляют один или несколько разделённых пробелами типов событий и необязательных пространств имён, а значения — функцию-обработчик, вызываемую для соответствующих событий.
    • selector
      Тип: String
      Строка селектора для фильтрации потомков выбранных элементов, при совпадении с которыми будет вызван обработчик. Если selector равен null или параметр опущен, обработчик вызывается всегда, когда событие достигает выбранного элемента.
    • data
      Тип: Anything
      Данные, передаваемые обработчику в свойстве event.data при возникновении события.

Метод .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 вместо последнего аргумента метода. В остальном описанные ниже формы ведут себя одинаково.

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

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

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

Если указан selector, обработчик события называется делегированным. Обработчик не вызывается при возникновении события непосредственно на элементе, которому он назначен, а вызывается только для элементов-потомков (внутренних элементов), соответствующих селектору. jQuery распространяет событие от его цели к элементу, которому назначен обработчик (то есть от самого внутреннего элемента к самому внешнему), и запускает обработчик для всех элементов на этом пути, соответствующих селектору.

Обработчики событий назначаются только текущему набору выбранных элементов; эти элементы должны существовать в момент вызова вашего кода .on(). Чтобы гарантировать, что элементы существуют и их можно выбрать, размещайте скрипты после этих элементов в HTML-разметке или выполняйте назначение обработчиков внутри обработчика готовности документа. Также можно использовать делегированные обработчики событий.

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

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

$( "#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.

Возврат значения 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 ).

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

Если для .on() указан аргумент data, отличный от 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 для делегированных событий в больших документах.

При фильтрации делегированных событий jQuery очень быстро обрабатывает простые селекторы вида tag#id.class. Поэтому "#myForm", "a.external" и "button" — быстрые селекторы. Делегированные события с более сложными селекторами, особенно иерархическими, могут работать в несколько раз медленнее, хотя для большинства приложений они всё равно достаточно быстры. Часто иерархических селекторов можно избежать, просто назначив обработчик в более подходящем месте документа. Например, вместо $( "body" ).on( "click", "#commentForm .addNew", addComment ) используйте $( "#commentForm" ).on( "click", ".addNew", addComment ).

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

Для некоторых событий есть отдельные страницы с описанием особенностей их использования. Полный список таких событий см. в разделе событий.

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

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

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

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

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

Список обработчиков элемента формируется при первом вызове события. Добавление или удаление обработчиков событий для текущего элемента не вступит в силу до следующей обработки события. Чтобы во время обработки события предотвратить выполнение других обработчиков для элемента, вызовите event.stopImmediatePropagation(). Такое поведение противоречит спецификации событий W3C. Чтобы лучше понять этот случай, рассмотрите следующий код:

var $test = $( "#test" );
 
function handler1() {
  console.log( "handler1" );
  $test.off( "click", handler2 );
}
 
function handler2() {
  console.log( "handler2" );
}
 
$test.on( "click", handler1 );
$test.on( "click", handler2 );

В приведённом выше коде handler2 всё равно выполнится при первом срабатывании, даже если его удалить с помощью .off(). Однако при последующих вызовах события click обработчик уже не будет выполнен.

Примеры:

Пример 1

При нажатии отобразить текст абзаца в диалоговом окне:

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

Пример 2

Передать данные обработчику события, указанному здесь по имени:

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

Пример 3

Отменить отправку формы и остановить всплытие события, вернув false:

$( "form" ).on( "submit", false );

Пример 4

Отменить только действие по умолчанию с помощью .preventDefault().

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

Пример 5

Остановить всплытие событий отправки формы, не отменяя отправку, с помощью .stopPropagation().

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

Пример 6

Передать данные обработчику события вторым аргументом .trigger()

$( "div" ).on( "click", function( event, person ) {
  alert( "Hello, " + person.name );
});
$( "div" ).trigger( "click", { name: "Jim" } );

Пример 7

Использовать второй аргумент .trigger() для передачи массива данных обработчику события

$( "div" ).on( "click", function( event, salutation, name ) {
  alert( salutation + ", " + name );
});
$( "div" ).trigger( "click", [ "Goodbye", "Jim" ] );

Пример 8

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

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>on demo</title>
  <style>
  p {
    color: red;
  }
  span {
    color: blue;
  }
  </style>
  <script src="https://code.jquery.com/jquery-4.0.0.js"></script>
</head>
<body>
 
<p>Has an attached custom event.</p>
<button>Trigger custom event</button>
<span style="display:none;"></span>
 
<script>
$( "p" ).on( "myCustomEvent", function( event, myName ) {
  $( this ).text( myName + ", hi there!" );
  $( "span" )
    .stop()
    .css( "opacity", 1 )
    .text( "myName = " + myName )
    .fadeIn( 30 )
    .fadeOut( 1000 );
});
$( "button" ).click(function () {
  $( "p" ).trigger( "myCustomEvent", [ "John" ] );
});
</script>
 
</body>
</html>

Демонстрация:

Пример 9

Одновременно назначить несколько обработчиков событий с помощью обычного объекта.

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

Демонстрация:

Пример 10

Нажмите на любой абзац, чтобы добавить после него ещё один. Обратите внимание: .on() позволяет обрабатывать событие click для любого абзаца, включая новые, поскольку событие обрабатывается постоянно присутствующим элементом body после того, как всплывает до него.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>on demo</title>
  <style>
  p {
    background: yellow;
    font-weight: bold;
    cursor: pointer;
    padding: 5px;
  }
  p.over {
    background: #ccc;
  }
  span {
    color: red;
  }
  </style>
  <script src="https://code.jquery.com/jquery-4.0.0.js"></script>
</head>
<body>
 
<p>Click me!</p>
<span></span>
 
<script>
var count = 0;
$( "body" ).on( "click", "p", function() {
  $( this ).after( "<p>Another paragraph! " + (++count) + "</p>" );
});
</script>
 
</body>
</html>

Демонстрация:

Пример 11

При каждом нажатии отображать текст соответствующего абзаца в диалоговом окне:

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

Пример 12

Отменить действие ссылки по умолчанию с помощью метода .preventDefault():

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

Пример 13

Назначить одному элементу несколько событий: одно для mouseenter и одно для mouseleave:

$( "#cart" ).on( "mouseenter mouseleave", function( event ) {
  $( this ).toggleClass( "active" );
});

© The jQuery Foundation and other contributors
Licensed under the MIT License.
https://api.jquery.com/on

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API