Spec-Zone.ru › jQuery

.on()

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

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

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

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

    • events
      Тип: Объект
      Объект, в котором строковые ключи представляют один или несколько разделенных пробелом типов событий и необязательных имен пространств имён, а значения представляют функцию обработчика, которая должна вызываться для события(ей).
    • selector
      Тип: Строка
      Строка селектора для фильтрации потомков выбранных элементов, которые будут вызывать обработчик. Если селектор null или опущен, обработчик всегда вызывается, когда он достигает выбранного элемента.
    • data
      Тип: Любой
      Данные, которые передаются обработчику в 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 вместо конечного аргумента метода. В других отношениях обе формы идентичны по своему поведению, как описано ниже.

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

Большинство событий браузера распространяются или пропагируются от самого глубокого, внутреннего элемента (целевой элемент события) в документе, где они происходят, до тела и элемента 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 для делегированных событий в больших документах.

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.

События focus и blur согласно спецификации W3C не должны «подниматься» (bubble), но 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 будет активировано.

Примеры:

Отобразить текст абзаца в диалоговом окне «Всплывающее окно» при нажатии на него:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

<!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-3.7.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>

Демо:

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

<!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-3.7.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>

Демо:

Нажмите на любой абзац, чтобы добавить новый после него. Обратите внимание, что .on() позволяет нажать на любое абзац — даже новые — так как событие обрабатывается постоянно присутствующим элементом 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-3.7.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>

Демо:

Отобразить текст каждого абзаца в диалоговом окне «Всплывающее окно» при каждом нажатии на него:

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

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

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

Прикрепить несколько событий — одно к 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