on()

Метод on() используется для установки обработчиков событий. Он включает в себя все необходимые опции для установки обработчиков событий: передача данных, делегирование и т.п. Удаляются обработчики событий с помощью метода off().

Методы bind(), delegate() и live() считаются устаревшими и не поддерживаются в версиях jquery-3.x. Их функции полностью реализованы в методе on().

Варианты использования

jQ_object.on(имя_события[, селектор][, данные], обработчик) => jQuery
Устанавливает один общий обработчик на одно или несколько событий.
jQ_object.on({
имя_события-1: обработчик-1,
имя_события-2: обработчик-2,
...}[, селектор][, данные]) => jQuery
Отдельно устанавливает обработчики различных событий.
имя_события
Строка, в которой через пробел указаны названия событий. В названии события можно использовать пространства имён.
селектор
Селектор для поиска элемента внутри исходного (на котором установлен обработчик). Обработчик будет запущен только в том случае, если событие всплывает от найденного элемента (элемент не обязательно должен быть целевым). Используется для делегирования событий.
данные
Данные в любом формате, которые будут доступны в объекте события в свойстве event.data.
обработчик
Функция, которая будет запускаться при каждом возникновении события. Значение false соответствует установке function() {return false;}.

Имена событий и пространства имён

Параметр имя_события указывается в виде строки, содержащей название события. Один обработчик можно установить сразу на несколько событий. Для этого названия событий необходимо перечислить через пробел.

Метод on() позволяет устанавливать обработчики не только на стандартные браузерные события, но и на собственные (нестандартные), необходимые разработчику. Нестандартное событие можно запустить с помощью метода trigger().

Тип события через точку может быть дополнен пространством имён. Например, click.action - событие click с пространством имён action. Этот параметр используется для удобства разработки. Если на одно событие установлено несколько обработчиков, тогда запустить или удалить конкретный обработчик можно только с использованием пространства имён. Пример:

$('#button').on({
  'click': handler_1,
  'click.name': handler_2
});
/* Элементу с id='button' установлено 2 обработчика на событие 'click' */
/* При нажатии на кнопку мыши будут выполнены оба обработчика */

$('#button').trigger('click');
/* Будут выполнены оба обработчика */

$('#button').trigger('click.name');
/* Будет выполнен обработчик handler_2 */

$('#button').off('click.name');
/* Будет удалён обработчик handler_2 */
/* .off('click') удалил бы все обработчики */

Пространства имён имеют сходство с классами в CSS. При установке обработчика можно указать сразу несколько пространств имён. При этом обратиться к нужному обработчику можно будет с использованием любого из них:

$('#button').on('click.name_1.name_2', handler);

$('#button').trigger('click.name_1');
/* Будет выполнен обработчик handler */

$('#button').off('click.name_2');
/* Будет удалён обработчик handler */

При установке обработчиков на некоторые стандартные события можно воспользоваться укороченной формой записи. Для этого используются одноимённые событиям методы: blur(), focus(), focusin(), focusout(), resize(), scroll(), click(), dblclick(), mousedown(), mouseup(), mousemove(), mouseover(), mouseout(), mouseenter(), mouseleave(), change(), select(), submit(), keydown(), keypress(), keyup(), contextmenu(). Например:

jQ_object.click([данные,] обработчик) => jQuery

В укороченной форме пространства имён и делегирование событий не поддерживаются.

Делегирование обработчиков событий

Если параметр селектор не задан или равен null, тогда используется прямая обработка события. То есть обработчик события запускается при каждом срабатывании события на элементах выборки. При этом нет никакой разницы, возникло ли событие непосредственно на выбранном элементе или всплыло по DOM-дереву от дочернего элемента.

Если при установке обработчика события указан параметр селектор, тогда обработчик считается делегированным. В этом случае обработчик сработает только в том случае, если событие, всплывая по DOM-дереву, прошло через дочерний элемент, удовлетворяющий селектору. Если при всплытии события ни один элемент не удовлетворяет селектору, тогда обработчик не запускается. Если событие всплывает через несколько элементов, удовлетворяющих селектору, тогда обработчик запускается для каждого из этих элементов.

Внутри обработчика переменная this хранит ссылку на тот элемент, для которого сработал обработчик. При прямой обработке события - это элемент, на котором установлен обработчик; для делегированного обработчика - элемент, удовлетворяющий селектору.

Пример прямой и делегированной обработки события click для элементов списка:

<ul>
  <li>Элемент 1</li>
  <li>Элемент 2</li>
  <li>Элемент 3</li>
</ul>

Прямая обработка события:

$('ul li').on('click', function() {
  alert($(this).text());
});

В данном случае обработчик установлен на каждый элемент <li>, то есть всего 3 обработчика. Недостатки прямой обработки события:

  • Если список будет иметь, например, 1000 элементов, тогда будет установлено 1000 обработчиков, что потребует больших вычислительных затрат.
  • Если после установки обработчиков в список будут добавлены новые элементы, тогда для них потребуется отдельно установить обработчики.

Избежать данных неприятностей можно, используя делегированную обработку события:

$('ul').on('click', 'li', function() {
  alert($(this).text());
});

В данном случае обработчик установлен всего на один элемент <ul>, но запускаться он будет только при клике на элементах <li>, как и при прямой обработке события. При этом обработчику не важно, сколько всего элементов в списке и когда они добавлены, так как он проверяет только соответствие селектору.

По стандарту W3C события focus и blur не всплывают по DOM-дереву, но в jQuery специально введены кроссбраузерные всплывающие аналоги focusin и focusout.

Для делегированной обработки событий focus и blur jQuery автоматически использует события focusin и focusout. Несмотря на это, желательно самостоятельно указывать названия focusin и focusout в тех случаях, когда события должны всплывать.

Cобытия load, scroll и error не всплывают по DOM-дереву и не имеют специальных всплывающих аналогов. Эти события не получится обработать делегированно.

Обработчики событий

Параметр обработчик может быть задан непосредственно анонимной функцией (как в примерах выше) или именем существующей функции:

function handler() {
  alert('Обработчик');
}

$('li').on('click', handler);

При срабатывании события в браузере или при запуске события с помощью метода trigger() в обработчик события первым параметром передаётся объект события, который содержит информацию о событии и может использоваться для управления событием. Данный объект немного изменён относительно того, который передаётся браузером по умолчанию. Это сделано для кроссбраузерности, так как объекты события в разных браузерах могут различаться. Оригинальный объект события, передаваемый браузером, доступен по ссылке event.originalEvent.

Если обработчик события возвращает значение false, тогда автоматически вызываются методы event.stopPropagation() и event.preventDefault().

В качестве обработчика вместо функции можно указать значение false, что будет соответствовать установке функции:

function() {
  return false;
}

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

Если задан параметр данные и он не имеет значение null или undefined, тогда в обработчике события можно получить эти данные в свойстве event.data.

Параметр данные может иметь любой тип. Однако, если данные передаются в виде строки, а параметр селектор не задан, тогда jQuery ошибочно примет переданную строку за селектор. Чтобы этого избежать, можно параметру селектор установить значение null или передать данные в другом виде. Наилучшим вариантом является передача данных в виде объекта. Во-первых, это позволяет избежать путаницы с селектором, а во-вторых, позволяет передать в обработчик сразу несколько значений.

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

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

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

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

Примеры

<html>
<head>
  <title>Работа с событиями в jQuery</title>
  <script type="text/javascript" src="js/jquery.js"></script>
</head>
<body>
  <button>Добавить строку</button>
  <ol>
    <li>Первая строка</li>
  </ol>
</body>
</html>
 
<script>
/* Делегированный обработчик для удаления любой строки */
$('ol').on('click', 'li', function() {
  $(this).remove();
});

/* Обработчик для добавления новой строки */
$('button').click(function() {
  var str = prompt('Введите строку');
  if (str !== null) {
    $('ol')
      .append('<li></li>')
      .children('li:last')
      .text(str);
  }
});
/* В данном случае используется метод click() для упрощения записи */
</script>
  1. Первая строка