Display a paragraph’s text in an alert when it is clicked:
Pass data to the event handler, which is specified here by name:
Cancel a form submit action and prevent the event from bubbling up by returning false :
Cancel only the default action by using .preventDefault() .
Stop submit events from bubbling without preventing form submit, using .stopPropagation() .
Pass data to the event handler using the second argument to .trigger()
Use the the second argument of .trigger() to pass an array of data to the event handler
Attach and trigger custom (non-browser) events.
Демонстрация:
Attach multiple event handlers simultaneously using a plain object.
Демонстрация:
Click any paragraph to add another after it. Note that .on() allows a click event on any paragraph—even new ones—since the event is handled by the ever-present body element after it bubbles to there.
events — тип(ы) обрабатываемых событий. Например "click", "resize" и.т.д. (список всех событий см. ниже). Если необходимо привязать обработчик сразу на несколько типов событий, нужно перечислить их через пробел: "click resize . "
selector — селектор по которому будут фильтроваться элементы, лежащие внутри уже найденных. В итоге, обработчик будет срабатывать только в том случае, если событие «поднялось» от одного из отфильтрованных элементов.
data — данные, передаваемые обработчику событий. В обработчике будут доступны в переменной event.data.
handler — функция, которая будет установлена в качестве обработчика. Вместо функции, можно указать значение false, это будет эквивалентно установке такой функции: function() .
с помощью этого метода можно установить на выбранные элементы сразу несколько разных обработчиков событий, каждый из которых будет реагировать на свой тип события.
events-map — объект, в котором нужно перечислить типы обрабатываемых событий и соответствующие им обработчики. Задается в формате , где events-i и handler-i соответствуют параметрам events и handler в первом варианте метода (описанном выше).
selector — см. выше.
data — см. выше..
Метод on() введен в jQuery-1.7, чтобы объединить три метода библиотеки, устанавливающие обработчики событий на элементы страницы: .bind(), .delegate(), .live(). Сами эти методы считаются теперь устаревшими, хотя еще поддерживаться. Установить обработчик, срабатывающий только один раз, по прежнему можно только с помощью отдельного метода .one().
Убрать установленный обработчик можно с помощью метода off().
Содержание
Типы обрабатываемых событий (параметр events)
В качестве первого параметра метода (тип события) может быть использовано любое строковое значение. Если необходимо обрабатывать одно из стандартных javascript-событий, то следует использовать следующие значения: blur, focus, focusin, focusout, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error. Каждый из этих типов имеет одноименный метод, являющейся краткой формой метода on() . К примеру, использование click(handler) равнозначно on("click", handler).
Если тип события не совпадет ни с одним из значений представленных выше, то будет воспринято jQuery как пользовательское событие. Такие события организуют сами пользователи (в смысле, пользователи библиотеки — программисты), генерируя их (события) с помощью методов trigger() и triggerHandler().
Пространство имен
Тип событий может быть задан с указанием пространства имен, например: on('click.name', handler). Здесь name является пространством имен, а click — типом события. Пространство имен позволяет разделить обработчики одних и тех же событий на подгруппы, которые, в последствии, будет легко отдельно вызывать (методом trigger()) и удалять (методом off()).
Можно указывать сразу несколько пространств имен: on('click.name1.name2', handler). Чтобы обратиться к такому событию, достаточно указать любое из них (или не указывать вовсе). Таким образом, пространства имен похожи по своей сути на классы в css.
Прямая и делегированная обработка (параметр selector)
Если этот параметр не задан или равен null, то обработчик события будет установлен на выбранные элементы и срабатывать, в случаях, когда событие возникло непосредственно на этих элементах или «поднялось» от их потомков. Это самая обычная обработка событий и ее называют непосредственной или прямой.
Однако, прямая обработка событий имеет свои недостатки. Допустим на странице есть список (ul), на элементах которого необходимо обрабатывать событие click. Если после установки соответствующих обработчиков, в список будут добавлены новые элементы, то они уже не будут реагировать на «клики», поскольку непосредственно к новым элементам, обработчики прикреплены не были. Эта особенность может породить много проблем и коварных логических ошибок.
Для таких случаев jQuery имеет возможность организовывать так называемую делегированную обработку событий. В этом случае, jQuery вместо заданного обработчика (в параметре handler) устанавливает собственный специальный обработчик. Причем он не устанавливается непосредственно на элементы, на которых необходимо обрабатывать события (назовем их inner-элементами), а на содержащие их элементы (назовем их outer-элементами. Получается, что inner находятся внутри outer). После того, как событие происходит на одном из элементов inner, оно начинает подниматься вверх по иерархии DOM. В какой то момент оно оказывается на одном из элементов outer, на котором срабатывает специально установленный обработчик, который проверяет, поднялось ли событие от одного из элементов inner. Если это так — запускается обработчик handler.
В случае делегированной обработки, добавление новых inner-элементов внутрь outer-элементов, не нарушает работоспособность скрипта — события исправно обрабатываются, даже если они возникли на новых inner элементах.
Чтобы организовать делегированную обработку, необходимо во втором параметре метода on задать селектор. В этом случае роль outer-элементов будут играть элементы к которым был применен метод, а роль элементов inner — элементы, находящиеся внутри outer и удовлетворяющие заданному селектору. То есть, если необходимо делегировано обрабатывать событие click на элементах списка, то следует делать это так:
Прямые обработчики в этой же ситуации устанавливались бы так:
Второе важное преимущество делегированной обработки это экономия вычислительных ресурсов. Допустим, есть список, содержащий несколько сотен или даже тысяч элементов. А нам нужно обрабатывать нажатие мышью по ним. Тогда, чтобы обрабатывать события напрямую, нужно будет привязать обработчик ко всем элементам, что потребует значительных вычислительных ресурсов. При делегированной обработке, будет установлен только один обработчик, который будет «ловить» события от всех элементов списка.
Небольшой пример. Так можно организовать делегированную обработку нажатия по элементам списка:
Делегированная обработка событий имеет и обратную сторону медали — чем ближе будет прикреплен ловящий события обработчик (outer-элемент) к вершине дерева DOM, тем чаще он будет вызываться, поскольку он будет ловить события всплывшие от большего количества элементов. При каждом таком вызове он будет производить проверку, не является ли источник этого события нужным элементом. Таким образом, чем выше в иерархии документа будет установлен делегированный обработчик, тем больше это будет вызывать вычислительных затрат. Поэтому, стоит привязывать делегированные обработчики как можно ближе к интересующим элементам.
По спецификации W3C, события focus и blur не имеют особенности подниматься вверх по иерархии DOM, однако в jQuery организованы их альтернативы — focusin и focusout, которые умеют «всплывать». Поэтому, если вы попытаетесь установить делегированные обработчики focus или blur, то jQuery по факту будет отслеживать focusin и focusout. Чтобы избежать возможных недоразумений, делегированную обработку приобретения и потери фокуса лучше осуществлять обработкой focusin и focusout.
Во всех браузерах, событие load, не всплывает вверх по иерархии. В IE 8 и младше, события paste и reset так же не обладают этим свойством. В связи с этим, не следует обрабатывать эти события делегированно. Привязывать обработчики этих событий следует непосредственно на элементы, на которых они происходят (без делегирования).
Обработчики событий (параметр handler)
В качестве параметра handler должна быть указана функция (или значение false, но об этом позже). Это может быть анонимная функция:
или именем заданной функции:
Когда происходит событие, jQuery передает в вызываемый обработчик объект event, в котором содержится вся вспомогательная информация по происходящему событию. Этот объект немного отличается от стандартных объектов событий, которые предоставляют браузеры (их получают обработчики, установленные обычными средствами javascript). Библиотека jQuery, изменяет некоторые поля для обеспечения кроссбраузерности. Так или иначе, всегда можно добраться и до нативного объекта события (тот, который предоставляет браузер), он лежит в поле event.originalEvent.
После возникновения, событие всегда всплывает по иерархии DOM вплоть до объекта document. Если при обработке события необходимо остановить всплытие, нужно вызвать метод event.stopPropagation() внутри обработчика. В результате, данное событие прекратит далнейшее всплытие по дереву DOM. Однако, если на текущем элементе были установлены другие невыполненные обработчики, они будут выполнены. Чтобы этого избежать нужно вместо stopPropagation() вызвать event.stopImmediatePropagation().
Многие события порождают выполнение связанных с ними действий. Например, сразу после того, как на ссылке происходит событие клик, происходит переход на другую страницу. Чтобы отменить выполнение этих действий, можно внутри обработчика события вызвать event.preventDefault(). Конечно, не все события порождают дополнительные действия, а так же, не все действия могут быть предотвращены (см. W3C спецификацию).
Если вместо функции в параметре handler задать false, то event.stopPropagation() и event.preventDefault() будут вызваны автоматически. Вообще, задание false идентично установке такого обработчика:
То есть, например после кода:
нажатие по ссылкам с классом disabled не будет приводить к переходу на другие страницы, а так же, событие не будет передаваться родительским элементам.
Переменная this внутри обработчика всегда содержит DOM-элемент, на котором отлавливается событие. При прямой обработке события это будет один из выбранных элементов, а при делегированной — элемент, лежащий внутри одного из выбранных элементов и удовлетворяющий параметру selector. Создать объект jQuery по this элементу можно так $(this).
Передача дополнительных данных в обработчик (параметр data)
Если параметр data задан, то он будет доступен в обработчике в even.data. В этот параметр можно передавать данные любого типа, однако, нужно быть осторожным при передаче строк — если при этом параметр selector не будет задан, то библиотека воспримет заданную строку в качестве этого параметра. Чтобы этого избежать нужно задать в параметре selector null. Удобнее всего задавать параметр data с помощью объектов. В этом случае, в обработчик можно передать сразу много данных.
Начиная с jQuery-1.4 один и тот же обработчик может быть привязан к одному элементу более одного раза. Поскольку вызов абсолютно идентичных действий более одного раза, вряд-ли, может быть полезным, эта особенность имеет ценность при различных заданных параметрах дата:
Помимо параметра data есть и другой способ передать параметры в обработчик — при ручном вызове событий с помощью методов .trigger() или .triggerHandler(), можно передавать дополнительные данные в их параметрах.
Дополнительные замечания
Большинство событий, как например нажатие мышью по элементу (click) происходят относительно редко и проблем с их обработкой практически не возникает. Однако такие события как mousemove и scroll могут происходить несколько раз в секунду. В этом случае, частое выполнение обработчиков может потребовать значительных вычислительных ресурсов компьютера и приводить к зависанию. Избежать этого можно, если грамотно организовать выполнение обработчиков. Например, стоит кэшировать вычисляемые величины, вместо того, чтобы считать их каждый раз заново. И в первую очередь следует кэшировать объекты jQuery, поскольку их создание зачастую требует весомых вычислительных затрат. Например, рассмотрим случай, когда нужно в элементе с идентификатором elm прописывать координаты мыши, когда она движется над элементом с классом mousemove-elm:
Если обработчики часто выполняемых событий не удается оптимизировать в достаточной степени, то следует сократить количество их вызовов, используя setTimeout:
Чтобы привязывать события к элементам страницы, jQuery требуется возможность устанавливать на них данные, в качестве свойств. Элементы object, embed и applet не имеют таких особенностей, поэтому установленные на них обработчики работать не будут.
Событие error объекта window, обладает нестандартными входными параметрами и возвращаемым значением, поэтому jQuery не поддерживает его обработку. Установить обработчик на это событие можно только стандартным методом — присвоив функцию величине window.onerror.
Примеры
Выведем на экран сообщение с текстом параграфа, по которому был совершен клик мышью:
Передадим данные в обработчик, который задан отдельной функцией:
Предотвратим отправку данных формы, а так же дальнейшее всплытие события, если переменная flag не равна true:
Предотвратим только отправку данных формы, если переменная flag не равна true. Таким образом несмотря на то, что данные не будут отправлены, а страница перезагружена, событие submit продолжит свой путь к вершине иерархии DOM — объекту document:
В примере показано, как можно осуществить обработку событий наведения, нажатия и двойного нажатия на элемент:
Определение и применение
jQuery метод .on() приcоединяет для выбранных элементов функцию обработчика события для одного, или нескольких событий.
jQuery синтаксис:
Добавлен в версии jQuery
Значения параметров
| Параметр | Описание |
|---|---|
| events | Один, или несколько разделенных пробелами типов событий (опционально допускается указывать пространство имен). Например: " click " или " click dblclick.myNamespace " |
| eventMap | Объект, содержащий строковый ключ, или ключи, определяющие тип события, а в качестве значения этих ключей выступает функция, которая будет выполнена каждый раз, когда конкретное событие срабатывает. Например: |
| selector | Строка селектора для фильтрации потомков выбранных элементов, запускающих событие. Обратите внимание, что если параметр отсутствует, или имеет значение null , то обработчик всегда вызывается при достижении выбранного элемента (не зависимо событие вызвано на элементе, или вложенном элементе). |
| data | Какие-либо данные, или объект, содержащий данные, которые будут переданы в обработчик событий при его срабатывании (свойство объекта Event event.data ). |
| handler | Функция, которая будет выполнена каждый раз, когда событие срабатывает. Функция в качестве параметра может принимать объект Event и при необходимости дополнительные параметры для решения конкретной задачи. Значение false также может использоваться в качестве сокращенной записи функции, которая имеет тело return false (при вызове возвращает значение false ). |
Пример использования
Имена событий и пространства имён
Любые имена событий могут быть использованы в качестве аргумента события. jQuery будет проходить через стандартные типы событий JavaScript, вызывая функцию обработчик, в то время когда браузер их генерирует, откликаясь на те, или иные действия пользователя, например такое событие как нажатие левой кнопкой мыши на элемент.
Обращаю Ваше внимание на то, что метод .trigger() может вызвать как стандартные имена событий браузера, так и пользовательские имена событий. Пользовательские имена событий должны содержать только алфавитно-цифровые символы, символ подчеркивания и двоеточие. Пространства имен, начинающиеся с подчеркивания, зарезервированы для использования библиотекой jQuery.
Пространства имен событий, или пользовательские имена событий упрощают удаление, или запуск необходимых обработчиков событий, по этой причине они зачастую используются при написании различных плагинов. Давайте рассмотрим использование пространств имен и пользовательских имен событий в jQuery на следующем примере:
В этом примере с использованием jQuery метода .on() мы приcоединяем для элемента (кнопка) функцию обработчика события myEvent (пользовательское событие) и назначаем два пространства имен.
Кроме того, с помощью обработчика событий " click " (клик левой кнопкой мыши) задаем функцию при нажатии на элемент , которая с помощью метода .trigger() вызывает два события " myEvent.myNamespace " и " myEvent.myAnotherNamespace " в результате чего в консоль будут выведены значения пространств имен объекта Event (свойство event.namespace).
Следующая часть примера демонстрирует работу с пространствами имен. С помощью метода .on() мы приcоединяем для элемента обработчики событий " click " и " click " пространства имен myNamespace2.
При нажатии на элемент будут срабатывать оба собтия и выводится два сообщения в консоль. Кроме того, мы с помощью обработчика событий " click " (клик левой кнопкой мыши) задаем функцию при нажатии на элемент
, которая вызывает событие " click " пространства имен myNamespace2, и затем с помощью метода .off() удаляет этот обработчик событий (при нажатии на будет выводиться только одно сообщение).
Результат нашего примера:
Пример использования jQuery метода .on() (пространства имен)
Прямые и делегированные события
Метод .on() позволяет задать как прямые, так и делегированные события. За это отвечает параметр selector метода, в том случае, если он опущен, или равен null устанавливается прямой обработчик события, он вызывается каждый раз, когда событие происходит на выбранных элементах, независимо от того, происходит ли это непосредственно на элементе, или всплывает от дочернего (вложенного) элемента.
В том случае, если параметр selector указан, то в этом случае будет установлен делегированный обработчик события,он вызывается в том случае, когда событие происходит непосредственно на привязанном элементе (указанном в параметре метода), а не на самом элементе. В этом случае jQuery контролирует всплытие события и запускает обработчик события для любых элементов по этому пути в дереве DOM, соответствующих значению указанному в параметре метода.
Давайте с Вами разберем когда использовать прямые, а когда делегированные события, в чем заключаются их преимущества и недостатки. Прямые обработчики событий привязываются только к выбранным в данный момент элементам, они должны существовать во время вызова метода .on(). Необходимо осуществлять привязку после того как документ будет готов, или необходимые элементы будут существовать в разметке HTML (дереве DOM).
Если какие-либо элементы добавляются динамически в документ, то Вам придется при работе с прямыми событиями каждый раз перевызывать метод .on(), чтобы привязать динамически добавленным элементам обработчик события, иначе на таких элементах обработчик не будет срабатывать. Второй вариант, который позволит Вам не отслеживать подобные ситуации, это использовать делегированные события для присоединения обработчиков событий. В этом заключается их основное преимущество.
Еще к одному преимуществу делегированной обработки событий можно отнести экономию ресурсов, она заключается в том, что Вам не надо привязывать событие к каждому конкретному элементу, которых может быть тысячи, а делегировать это одному конкретному элементу.
Обращаю Ваше внимание, что при работе с делегированными событиями для экономии ресурсов рекомендуется размещать элемент, которому делегирована обработка события ближе по дереву DOM к отслеживаемым элементам. Кроме того, делегированные события не работают для SVG (масштабируемая векторная графика).
Перейдем к рассмотрению примера:
В этом примере с использованием jQuery метода .on() мы приcоединяем для элемента (кнопка) функцию обработчика события " click ", которая с помощью метода .append() вставляет содержимое (элемент списка ) в конец элемента .
С использованием jQuery метода .on() мы создали прямое событие, которое при клике левой кнопкой мыши на элементе , вложенном в элемент вызывает функцию, которая методом .text() изменяем текст элемента и методом .css() изменяет цвет текста.
Кроме того, с использованием jQuery метода .on() мы создали делегированное событие, которое при двойном клике левой кнопкой мыши на элементе , вложенном в элемент вызывает функцию, которая методом .text() изменяем текст элемента и методом .css() изменяет цвет текста.
Обратите внимание на отличие в синтаксисе между прямыми и делегированными событиями. Казалось бы, они делают одно и тоже, но попробуйте добавить дополнительный элемент . Как вы можете заметить прямые события не будут срабатывать, в этом и заключается основное преимущество делегированных событий.
Результат нашего примера:
Обработчик события для динамически добавленных элементов
Обработчик событий и его среда
Обязательный параметр handler является функцией, или значением false в том случае, если в качестве первого параметра передается объект eventMap, содержащий ключ, или ключи, а в качестве значения этих ключей выступает функция. Допускается передавать анонимную функцию, или передавать имя, объявленной именованной функции:
Когда браузер запускает событие, или когда jQuery метод .trigger() был вызван, jQuery передает обработчику объект события ( Event ), он может использоваться для анализа и изменения состояния события, например чтобы обеспечить кроссбраузерность. Этот объект представляет из себя нормализованный набор данных, предоставленных браузером пользователя. Оригинальный объект по прежнему будет доступен в свойстве event.originalEvent .
По умолчанию большинство событий переходят от исходной цели события к объекту document . На каждом элементе по пути следования jQuery вызывает все соответствующие обработчики событий, которые были присоединены.
Функция обработчик может предотвратить дальнейший подъем события по дереву DOM, предотвращаю запуск обработчиков этих элементов путем вызова метода event.stopPropagation(). Однако все остальные обработчики, прикрепленные к текущему элементу, будут запущены, чтобы предотвратить это поведение, вы можете вызвать метод объекта event.stopImmediatePropagation().
Обработчик может вызывать метод event.preventDefault(), который позволяет отменить любое действие, установленное по умолчанию, например, это полезно, чтобы предотвратить переход на другую страницу при нажатии на ссылку. Учтите, что не все события имеют действия по умолчанию, и не все действия по умолчанию могут быть отменены.
Если функция обработчик возвращает false , то в этом случае автоматически будут вызваны методы event.stopPropagation() и event.preventDefault(). Значение параметра false в качестве обработчика события равнозначно следующему коду:
Например, чтобы предотвратить переход на другую страницу при нажатии на элемент , достаточно приcоединить для них следующее событие:
Когда jQuery вызывает обработчик, ключевое слово this ссылается на элемент, который доставил это событие, для прямых событий это элемент, к которому событие было присоединено, а для делегированных событий это один из элементов, который был указан в параметре selector.
Обратите внимание, что this может быть не равен свойству event.target в том случае, если событие всплыло от потомков элемента. Для того, чтобы конкретный элемент можно было использовать с методами jQuery необходимо создать объект jQuery из одного элемента следуюшим образом:
Передача данных в обработчик события
Если вместе с методом .on() используется аргумент data и его значение не равно null , или undefined , то оно передается в обработчик события и доступно в свойстве event.data каждый раз, когда событие срабатывает. Аргумент data может быть любого типа, но если используется строковое значение, то селектор должен быть указан, или передан как null , чтобы данные не были приняты за селектор. Рекомендуется использовать простой объект для передачи нескольких значений в качестве свойств. Начиная с версии jQuery 1.4, один и тот же обработчик событий может быть связан с элементом несколько раз:
В качестве альтернативы вы можете передавать необходимые данные обработчику событий с помощью второго аргумента метода .trigger(), или метода .triggerHandler().
Давайте рассмотрим следующий пример, который демонстрирует как с помощью метода .trigger() передать произвольные данные через объект события:
В этом примере мы инициализировали переменную, которая содержит функцию, которая при вызове возвращает случайное число от 0 до 1. С помощью метода .on() для элемента установили обработчики пользовательских событий " login " и " logoff ". В качестве второго параметра метода передали объект, содержащий данные, которые будут переданы в обработчик событий при его срабатывании (свойство объекта Event — event.data). Обратите внимание, что в качестве значения свойства нашего объекта будет использован результат вызова функции, содержащайся в созданной нами переменной.
Для события " login " мы передаем функции, которая будет выполнена каждый раз, когда событие срабатывает в качестве параметров, объект Event и два дополнительных параметра, значения которых она получит при вызове метода .trigger() для данного типа событий. Функция выводит в консоль значения дополнительных параметров и значение свойства secretkey, переданное в объект данных (свойство объекта Event — event.data).
Для события " logoff " мы передаем функции, которая будет выполнена каждый раз, когда событие срабатывает в качестве параметра объект Event . Функция выводит в консоль значения свойств объекта Event , включая пользовательские свойства, которые мы передаем в объект при вызове метода .trigger() для данного типа событий и значение свойства secretkey, переданное в объект данных (свойство объекта Event — event.data).
Для того, чтобы выполнить все функции обработчики событий, присоединенные у выбранного элемента для типа событий " login " и " logoff " мы используем jQuery метод.trigger(). В первом случае мы указываем в качестве первого параметра метода .trigger() строковое значение, которое соответствует типу событий " login " и передаем массив данных. Обратите внимание, что данные содержащиеся под нулевым индексом в массиве будут соответствовать первому дополнительному параметру в обработчике этого события.
Во втором случае мы указываем в качестве параметра метода .trigger() объект данных, содержащий пары ключ-значение, который мы передадим в объект события jQuery ( Event ). Обратите внимание, что свойство type этого объекта должно соответствовать событию, которое мы хотим инициировать, иначе обработчик события вызван не будет.
Результат нашего примера:
Пример использования jQuery метода .trigger() (передача дополнительных данных)
Дополнительная информация
В большинстве случаев такое событие как " click " происходит сравнительно нечасто, и не заставляет нас задумываться о производительности, так как в этом случае это не является серьезной проблемой. Однако, такие события как " mousemove ", или " scroll ", могут срабатывать десятки раз в секунду, в этих случаях производительность может значительно снижаться, что может стать для нас большой проблемой.
Производительность может быть увеличена за счет сокращения объема работы, выполняемой в самом обработчике события, кэширования данных, необходимых обработчику, а не постоянного их пересчета, в том числе за счет ограничения скорости количества фактических обновлений страницы с помощью метода setTimeout() .
Такие события как " focus " и " blur " по спецификации W3C не всплывают, но в jQuery определены кроссбраузерные события " focusin " и " focusout ", которые подлежат всплытию. Когда события " focus ", или " blur " используются для присоединения делегированных обработчиков событий, jQuery отображает имена и передает их как " focusin " и " focusout " соответственно. Для обеспечения согласованности и ясности используйте имена типов событий " focusin " и " focusout ".
Во всех браузерах события " load ", " scroll " и " error " (например, в элементе ) не всплывают. В Internet Explorer 8 и ниже события " paste " и " reset " не всплывают. Такие события не поддерживаются для использования с делегированием, но их можно использовать, когда обработчик событий непосредственно присоединен к элементу, генерирующему это событие.





