Статьи

Комплексный взгляд на события в jQuery

Эта статья была рецензирована Верном Анчетой и Камило Рейесом . Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!

Почти все пользовательские взаимодействия на веб-странице могут быть записаны в jQuery как события. События важны в том смысле, что они позволяют вам адекватно реагировать на действия пользователя. Например, вы можете написать код, который меняет цвет фона веб-страницы на основе событий нажатия кнопки или прокрутки.

В jQuery есть много методов ярлыков, таких как contextmenu() , hover() и keyup() , для работы с различными событиями. В дополнение к выделенным методам, jQuery также предоставляет универсальный метод on который позволяет вам присоединить обработчик для любого события: on('eventName', handler) . Имейте в виду, что эти методы являются просто обертками вокруг стандартных событий DOM, и вы можете добавить обработчики для этих событий в простом JavaScript.

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

События браузера

В этой категории есть три события. Это error , resize и scroll . Событие error вызывается, когда такие элементы, как изображения, загружаются неправильно. Начиная с версии jQuery 1.8 его метод ярлыков устарел, поэтому вместо него следует использовать on('error', handler) .

Событие изменения размера

Это событие вызывается всякий раз, когда изменяется размер окна браузера. Различные браузеры могут вызывать обработчик изменения размера по-разному в зависимости от реализации. Браузеры на основе Internet Explorer и WebKit непрерывно вызывают обработчик, в то время как браузеры, такие как Opera, вызывают его только в конце события изменения размера.

Этот фрагмент кода ниже меняет src изображения в зависимости от ширины окна.

 $(window).resize(function() { var windowWidth = $(window).width(); if (windowWidth <= 600) { $("img").attr("src", "image-src-here.jpg"); // Image src changed at this point. } }); 

Эта демонстрация CodePen показывает событие в действии:

Событие прокрутки

Элемент может отключить это событие, когда пользователь прокручивает в другую позицию в этом конкретном элементе. Помимо объекта window , любой элемент с полосой прокрутки может вызвать это событие. Например, любой элемент со свойством overflow установленным в scroll, или любой прокручиваемый iframe, может вызвать это событие.

Имейте в виду, что обработчик вызывается всякий раз, когда изменяется положение прокрутки. Причина прокрутки не имеет значения. Это может быть вызвано нажатием клавиш со стрелками, нажатием или перетаскиванием полосы прокрутки или использованием колеса прокрутки мыши. В приведенном ниже коде мы проверяем, прокрутил ли пользователь более 500 пикселей, и выполняем некоторые действия.

 $(window).scroll(function() { if ($(window).scrollTop() >= 500) { $("#alert").text("You have scrolled enough!"); // Update the text inside alert box. } }); 

В демонстрации CodePen ниже, если вы продолжаете прокручивать страницы и приближаетесь к концу, вы должны увидеть уведомление о том, что вы почти в нижней части веб-страницы:

События загрузки документов

В jQuery есть методы для трех событий, которые запускаются в зависимости от состояния документа или DOM. Это load , unload и ready .

load() может использоваться для присоединения обработчика к любому элементу, который загружает внешний ресурс, такой как изображения, сценарии, iframes и сам объект window . Событие возникает, когда элемент, к которому он присоединен, вместе со всеми подэлементами полностью загружен. При использовании с изображениями это создает несколько проблем. Во-первых, это не правильно всплывает дерево DOM. Вторая проблема заключается в том, что он не является ни надежным, ни кросс-браузерным.

Событие unload вызывается, когда пользователь уходит с веб-страницы. Это может произойти, потому что пользователь нажал на ссылку, набрал новый URL в адресной строке или закрыл окно браузера. Это событие также вызывается перезагрузкой страницы. Обратите внимание, что использование preventDefault() не отменяет событие unload . Более того, вызовы alert() , confirm() и prompt() будут игнорироваться большинством браузеров в этом обработчике событий, что означает, что приведенный ниже код не будет работать:

 $( window ).unload(function() { alert("Please don't leave!"); // Won't work. }); 

Начиная с версии 1.8, load() и unload() устарели.

Готовое событие

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

Демонстрация CodePen ниже загружает изображение с высоким разрешением. Вы заметите, что DOM становится готовым до полной загрузки изображения.

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

События клавиатуры

События клавиатуры могут быть вызваны любым взаимодействием пользователя с клавиатурой. Каждое такое событие будет содержать информацию о нажатой клавише и типе события. В jQuery есть три сочетания клавиш: keydown() , keyup() и keypress() .

События Keyup и Keydown

Как следует из названия, keyup запускается, когда пользователь отпускает клавишу на клавиатуре, а keydown запускается всякий раз, когда пользователь нажимает клавишу на клавиатуре. Обработчики для обоих этих событий могут быть присоединены к любому элементу, но сработают только обработчики на элементе, который в данный момент находится в фокусе.

Рекомендуется использовать свойство which объекта event чтобы определить, какая клавиша была нажата. Это связано с тем, что браузеры используют разные свойства для хранения этой информации, а jQuery нормализует свойство which для надежного извлечения этой информации.

Еще одна вещь, которую стоит помнить: оба эти события не делают различий между a и shift + a . В последнем случае сдвиг и a регистрируются отдельно. В приведенном ниже коде я предоставляю пользователю окно предупреждения, в котором регистрируется любое событие keydown . При нажатии клавиши y определенный элемент удаляется из DOM.

 $("#alert").keydown(function(event) { switch (event.which) { case 89: // keycode for y $("#element").remove(); // Remove element from the DOM break; } }); 

Ключевое событие

Это событие похоже на событие keydown . Одним из основных отличий является то, что клавиши-модификаторы и непечатаемые клавиши, такие как Shift , Esc и т. Д., Не keypress событие keypress . Я не могу подчеркнуть это достаточно, когда говорю, что вам не следует использовать событие нажатия клавиш для перехвата специальных нажатий клавиш, таких как клавиши со стрелками. keypress используется, когда вы хотите узнать, какой символ был введен, например, A или a .

Фрагмент кода ниже скрывает элемент на основе нажатой клавиши:

 $("body").keypress(function(event) { switch (event.keyCode) { case 75: // 75 stands for capital K in keypress event $(".K").css("display", "none"); break; } }); 

События мыши

События мыши запускаются, когда пользователь взаимодействует с помощью указательного устройства, такого как мышь. События могут быть основаны на щелчках, таких как click , dblclick и contextmenu или на движении, например mouseenter , mouseleave и mousemove . В этом разделе я кратко расскажу обо всех из них и включу несколько демонстраций, чтобы проиллюстрировать незначительные различия между ними.

События на основе кликов

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

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

Событие contextmenu вызывается после щелчка правой кнопкой мыши на элементе, но перед отображением контекстного меню. Это означает, что вы можете предотвратить отображение контекстного меню по умолчанию, используя соответствующий код в обработчике событий.

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

 $("img").contextmenu(function(event) { event.preventDefault(); $("#custom-menu") .show().css({ top: event.pageY + 10, left: event.pageX + 10 // Show the menu near the mouse click }); }); $("#custom-menu #option").click(function() { $("img").toggleClass("class-name"); // Toggle an image class. }); 

Эта демонстрация применяет стили CSS к изображению при нажатии и имеет настраиваемое контекстное меню:

События на основе движения

Некоторые события основаны на перемещении указателя мыши над или внутри и вне элемента. Существует шесть методов событий, основанных на движении.

Давайте начнем с событий mouseover и mouseenter . Как следует из названия, оба эти события запускаются, когда указатель мыши входит в элемент. Аналогично, mouseleave и mouseleave когда указатель мыши покидает элемент.

Одно из различий между mouseleave и mouseleave заключается в том, что первый срабатывает, только если указатель мыши перемещается за пределы элемента, с которым он связан. С другой стороны, mouseout запускается даже для движений вне любых потомков этого элемента. Точно такая же разница существует между mouseenter mouseover и mouseenter mouseover .

Давайте посмотрим, как изменяется количество событий mouseenter и mouseover зависимости от движений мыши. Попробуйте войти в большую синюю коробку с правой стороны и остановитесь прямо перед тем, как войти в правую розовую коробку. mouseenter mouseover и mouseenter mouseover должны иметь значение 1. Если вы переместитесь влево и войдите в розовое поле, счетчик mouseover изменится на два. Это происходит из-за всплытия событий при mouseover . Событие при mouseover на розовом поле «всплывает» до внешнего синего поля, увеличивая количество событий при mouseover на 1. При перемещении влево и остановке между обоими розовыми прямоугольниками событие при mouseover запускается снова. К тому времени, когда вы достигнете левого конца синего поля, количество событий при mouseenter mouseover должно быть равно 5, а количество событий при mouseenter должно быть равно 1.

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

События Mousemove и Hover

Событие mousemove запускается, когда указатель мыши перемещается внутри элемента. Он срабатывает всякий раз, когда движется мышь, даже если он составляет всего один пиксель. Следовательно, сотни событий могут быть запущены за короткое время. Как вы можете себе представить, выполнение сложных операций внутри обработчика событий может вызвать задержку браузера. Желательно сделать mousemove события mousemove максимально эффективным и mousemove когда он больше не нужен.

hover срабатывает только тогда, когда указатель мыши либо входит, либо покидает элемент. Существует два способа вызова метода hover . Первый из них:

 $("your-selector").hover( handlerIn, handlerOut ); 

Здесь handlerIn() выполняется, когда указатель мыши входит в элемент, и handlerOut() когда указатель мыши покидает его. Второй способ:

 $("your-selector").hover(handlerInOut); 

На этот раз handlerInOut та же функция handlerInOut выполняется как при входе, так и при выходе из элемента.

Примечание: эта демонстрация использует эффекты фильтра CSS, которые не поддерживаются в IE.

События формы

Формы вездесущи в Интернете. Почти каждый пользователь заполняет форму в какой-то момент. В jQuery есть специальные методы, предназначенные для обработки событий формы. Эти события могут быть вызваны изменением значения или потерей фокуса. Есть семь формальных событий, и мы обсудим их все одно за другим.

События Blur, Focus, Focusin и Focusout

Событие focus запускается всякий раз, когда элемент получает фокус. Это применимо только к элементам формы и тегам привязки. Чтобы активировать focus на любом другом элементе, вам нужно установить свойство tabindex элемента. Имейте в виду, что установка фокуса на скрытые элементы приведет к ошибке в Internet Explorer. Если вам нужно вызвать событие фокуса без явной установки фокуса, вы можете вызвать метод triggerHandler( "focus" ) .

Событие blur запускается всякий раз, когда элемент теряет фокус. В старых браузерах это событие применимо только к элементам формы.

В отличие от события focus , focusin срабатывает всякий раз, когда любой элемент или его потомок получает фокус. Точно так же focusout срабатывает всякий раз, когда какой-либо элемент или его потомки теряют фокус. Итак, если вы хотите, чтобы события всплыли, вы должны использовать эти два события.

Выбор, изменение и отправка событий

Событие change вызывается, когда элемент меняет значение. Это событие применимо только к элементам <input> , <textarea> и <select> . В случае флажков, переключателей и полей выбора это событие вызывается, как только пользователь делает какой-либо выбор. Для других элементов он срабатывает только после того, как элемент теряет фокус. Также обратите внимание, что это событие не будет запущено, если значение элемента ввода изменяется с помощью JavaScript.

Событие select запускается, когда пользователь делает выделение текста внутри элемента. Это событие более ограничено по объему и применяется только к элементам <input type="text"> и <textarea> . Если вы хотите получить выделенный текст, вам нужно использовать кросс-браузерный плагин jQuery.

Событие submit наступает, когда пользователь пытается отправить форму. Вы можете прикреплять обработчики только к элементам формы. Чтобы вызвать это событие, пользователи должны будут щелкнуть элементы <input type="submit"> , <button type="submit"> или <input type="image"> . Интересно, что событие submit JavaScript не всплывает в Internet Explorer. Тем не менее, это поведение было нормализовано во всех браузерах, начиная с версии jQuery 1.4.

Изменения в jQuery 3

Начиная с версии jQuery 1.8, методы load , error и unload устарели. Метод load() по своей природе неоднозначен. Этот метод может означать либо загрузку AJAX, либо фактическое срабатывание события загрузки. Аналогичным образом, метод error также может быть перепутан с jQuery.error() . Теперь в jQuery 3 эти методы были окончательно удалены. Теперь вам нужно будет использовать метод on для регистрации этих слушателей событий.

Последние мысли

В этой статье я рассмотрел все основные методы событий jQuery, а также различия между похожими событиями. Знание того, когда использовать keypress вместо keypress поможет вам избежать проблем и сэкономить драгоценное время. Несмотря на то, что jQuery может подключаться к событиям DOM с помощью простого JavaScript, он немного нормализует различия между браузерами, что может быть преимуществом в зависимости от того, какие браузеры должен поддерживать ваш сайт / приложение.

Чтобы узнать больше о событиях, вы можете посетить официальную документацию jQuery . Если у вас есть какие-либо вопросы или советы, связанные с использованием событий в jQuery, пожалуйста, оставьте комментарий.