cpp

Методы on() и one(): назначение обработчиков событий

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

Форматы метода on():

on(<Тип события>[, <Селектор>][, <Данные>], <Функция обратного вызова>)
on(<Объект>[, <Селектор>][, <Данные>])

В параметре <Тип события> могут быть указаны следующие значения в виде строки:

  • события документа: load, beforeunload, unload, resize, scroll;
  • события мыши: click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, contextmenu;
  • события клавиатуры: keydown, keypress, keyup;
  • события формы: focus, blur, focusin, focusout, change, select, submit;
  • прочие события, включая пользовательские.

Все эти события мы уже рассматривали в предыдущих разделах. Например, назначить обработчик события onclick для всех кнопок можно так:

$(':button').on('click', function() {
   console.log('Вы щелкнули на кнопке');
});

Результат будет абсолютно таким же, как и при использовании метода click():

$(':button').click( function() {
   console.log('Вы щелкнули на кнопке');
});

В параметре <Тип события> может быть указана комбинация событий через пробел. Добавим стилевой класс bg-warning при наведении курсора мыши на абзац, а при уходе курсора удалим класс:

$('p').on('mouseenter mouseleave', function() {
   $(this).toggleClass('bg-warning');
});

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

$('#btn1')
   .on('click', function() {
      console.log('Первый обработчик');
   })
   .on('click', function() {
      console.log('Второй обработчик');
   });

При щелчке на кнопке с идентификатором btn1 будут последовательно выведены два сообщения:

Первый обработчик
Второй обработчик

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

$('#btn1')
   .on('click', function() {
      console.log('Первый обработчик');
      return 123;
   })
   .on('click', function(e) {
      console.log('Второй обработчик');
      console.log(e.result); // 123
   });

С помощью метода on() можно назначать обработчики пользовательских событий. Вызов пользовательских событий осуществляется при помощи методов trigger() и triggerHandler(). Создадим обработчик пользовательского события, а затем сгенерируем событие после нажатия кнопки:

$('#div1').on('myEvent', function() {
   console.log('Обработка собственного события');
});
$('#btn1').on('click', function() {
   $('#div1').trigger('myEvent');     // Вызов события
});

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

$('#div1').on('myEvent.myNamespace', function(e) {
   console.log('Обработка собственного события');
   console.log('Пространство имен: ' + e.namespace);
});
$('#btn1').on('click', function() {
   $('#div1').trigger('myEvent.myNamespace'); // Вызов события
});

С помощью необязательного параметра <Данные> можно передать значения в обработчик. Переданное значение внутри функции обратного вызова доступно через свойство data объекта события:

<Значение> = <Объект event>.data

Рассмотрим пример:

function handler1(e) {
   var msg  = 'msg1 = ' + e.data.msg1 + '\n';
       msg += 'msg2 = ' + e.data.msg2;
   console.log(msg);
   return false;    // Перехода по ссылке не будет
}
$('a').on(
   'click',                                      // Событие
   { msg1: 'Сообщение 1', msg2: 'Сообщение 2' }, // Наши данные
   handler1                                      // Ссылка на функцию
);

При щелчке на ссылке будет выведено сообщение со значениями переданных данных:

msg1 = Сообщение 1
msg2 = Сообщение 2

Данные могут быть произвольного типа, однако, если передается строка, то в параметре <Селектор> нужно указать значение null:

$('a').on('click', null, 'myData', function(e) {
   console.log(e.data); // myData
   return false;        // Перехода по ссылке не будет
});

В качестве параметра <Функция обратного вызова> указывается ссылка на функцию следующего формата:

function <Название функции>([<Объект event>[, <Аргументы>]]) {
   // ...
}

Элемент, в котором обрабатывается событие, доступен внутри функции через указатель this. Обратите внимание на то, что указатель this ссылается на элемент объектной модели документа, а не на элемент коллекции jQuery. Если в параметре <Объект event> указана переменная, то через нее можно обратиться к свойствам объекта event. В параметре <Аргументы> можно указать несколько переменных через запятую. Значения в эти переменные передаются с помощью второго параметра методов trigger() и triggerHandler(). Пример:

$('#div1').on('myEvent', function(e, msg) {
   console.log('Обработка собственного события. ' + msg);
});
$('#btn1').on('click', function() {
   $('#div1').trigger('myEvent', ['Наше сообщение']);
});

Результат в окне консоли после нажатия кнопки:

Обработка собственного события. Наше сообщение

Если внутри функции обратного вызова только возвращается значение false, то вместо ссылки на функцию достаточно указать значение false. Запретим переход по всем ссылкам:

$('a').on('click', false);

Эта инструкция полностью идентична следующей:

$('a').on('click', function() {
   return false;
});

В параметре <Объект> во втором формате метода on() указывается объект с названиями событий и функциями обратного вызова. Благодаря этому можно назначить обработчики сразу для нескольких событий:

$('a').on( {
   mouseover: function() {
      $(this).css('color', 'red');
      console.log('Событие onmouseover');
   },
   mouseout: function() {
      $(this).css('color', 'black');
      console.log('Событие onmouseout');
   }
} );

Назначение обработчиков событий из предыдущих примеров имеет один недостаток. Если мы назначили обработчик, а затем добавили новые элементы, то для этих элементов обработчики событий автоматически назначены не будут:

<input type="button" value="Кнопка">

$(':button').on('click', function() {
   var html = '<input type="button" value="Новая кнопка">';
   $(this).after('<br>' + html);
});

В этом примере мы назначили обработчик события onclick для всех кнопок. После щелчка на кнопке добавляется новая кнопка. Если попробовать на ней щелкнуть, то никаких изменений не произойдет.

Для динамического назначения обработчиков событий нужно указать селектор в параметре <Селектор>, при этом обработчик следует назначить для родительского элемента или документа:

$(document).on('click', ':button', function() {
   var html = '<input type="button" value="Новая кнопка">';
   $(this).after('<br>' + html);
});

В этом случае, если щелкнуть на новой кнопке, появится еще одна кнопка. Щелчок на этой кнопке приведет к созданию еще одной кнопки и т. д. Такие обработчики называются делегированными.

Получить ссылку на родительский элемент внутри обработчика позволяет свойство delegateTarget объекта события, а ссылка на текущий элемент доступна через свойство currentTarget. Если параметр <Селектор> не указан, то значение свойства delegateTarget будет совпадать со значением свойства currentTarget. Пример указания родительского элемента:

<div id="div1">
  <input type="button" value="Кнопка">
</div>

$('#div1').on('click', ':button', function(e) {
   var html = '<input type="button" value="Новая кнопка">';
   $(this).after('<br>' + html);
   console.log('delegateTarget: ' + e.delegateTarget);
   console.log( $(e.delegateTarget).prop('id') );      // div1
   console.log('currentTarget: ' + e.currentTarget);
   console.log( $(e.currentTarget).val() );
});

В этом случае обработчик будет динамически добавляться, если кнопка расположена внутри элемента с идентификатором div1.

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

one(<Тип события>[, <Селектор>][, <Данные>], <Функция обратного вызова>)
one(<Объект>[, <Селектор>][, <Данные>])

Все параметры аналогичны одноименным параметрам метода on(). Обработаем один щелчок на любой кнопке:

$(':button').one('click', function() {
   console.log('Вы щелкнули на кнопке');
});

После первого щелчка на кнопке будет выведено указанное сообщение, а после второго обработчик вызван уже не будет.

Пример генерации и обработки пользовательского события с пространством имен:

$('#div1').one('myEvent.myNamespace', function(e) {
   console.log('Обработка собственного события');
   console.log('Пространство имен: ' + e.namespace);
});
$('#btn1').on('click', function() {
   $('#div1').trigger('myEvent.myNamespace'); // Вызов события
});

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

$('a').one( {
   mouseover: function() {
      $(this).css('color', 'red');
      console.log('Событие onmouseover');
   },
   mouseout: function() {
      $(this).css('color', 'black');
      console.log('Событие onmouseout');
   }
} );

Передадим пользовательские данные в обработчик:

$('a').one(
   'click',                                      // Событие
   { msg1: 'Сообщение 1', msg2: 'Сообщение 2' }, // Наши данные
   function(e) {
      var msg  = 'msg1 = ' + e.data.msg1 + '\n';
          msg += 'msg2 = ' + e.data.msg2;
      console.log(msg);
      return false;    // Перехода по ссылке не будет
   }
);

Учебник по jQuery и AJAX
Учебник по jQuery и AJAX в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов

cpp