Работа с событиями в jQuery. Часть 4. События клавиатуры


Содержание материала:

Использование прямых методов событий

Веб-программирование — jQuery — Использование прямых методов событий

»» В данной статье используется исходный код для примеров. Сохраните эту страницу для тестирования приведенных ниже примеров.

В библиотеке jQuery определен ряд так называемых , позволяющих связывать часто используемые события с функциями-обработчиками. Ниже эти функции описаны с аргументом function, который задает функцию-обработчик для данного события. Это наиболее распространенный способ работы с событиями, который полностью эквивалентен вызову метода bind(), но требует меньших усилий по набору текста (по крайней мере, с моей точки зрения) и более отчетливо показывает, с каким именно событием связывается обработчик.

Пример использования одного из прямых методов представлен ниже:

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

Здесь в документ добавляется кнопка (элемент button), после щелчка на которой выбираются элементы img и вызываются их обработчики события mouseenter. Ниже перечисляются различные категории прямых методов и событий, которым они соответствуют:

Прямые методы jQuery для работы с событиями

Метод Описание
События документа
load() Соответствует событию load, которое срабатывает после окончания загрузки всех подчиненных элементов и ресурсов документа
ready() Срабатывает после обработки всех элементов, содержащихся в документе, и завершения построения DOM-структуры
unload() Соответствует событию unload, которое срабатывает, когда пользователь покидает страницу
События браузера
error() Соответствует событию error, которое срабатывает при возникновении проблем с загрузкой внешних ресурсов, например изображений
resize() Соответствует событию resize, которое срабатывает при изменении размера окна браузера
scroll() Соответствует событию scroll, которое срабатывает при использовании полос прокрутки
События мыши
click() Соответствует событию click, которое срабатывает, когда пользователь выполняет щелчок мышью
dbclick() Соответствует событию dbclick, которое срабатывает, когда пользователь выполняет двойной щелчок мышью
focusin() Соответствует событию focusin, которое срабатывает при использовании полос прокрутки
focusout() Соответствует событию focusout, которое срабатывает, когда элемент теряет фокус
hover(), hover(функция, функция) Запускается, когда указатель мыши перемещается в область элемента или покидает ее. Если указана только одна функция, она используется в обоих случаях
mousedown() Соответствует событию mousedown, которое срабатывает при щелчке мышью над элементом
mouseenter() Соответствует событию mouseenter, которое срабатывает при наведении указателя мыши на область экрана, занимаемую элементом
mouseleave() Соответствует событию mouseleave, которое срабатывает, когда указатель мыши покидает область экрана, занимаемую элементом
mousemove() Соответствует событию mousemove, которое срабатывает, когда указатель мыши перемещается в пределах области экрана, занимаемой элементом
mouseout() Соответствует событию mouseout, которое срабатывает, когда указатель мыши покидает область экрана, занимаемую элементом
mouseover() Соответствует событию mouseover, которое срабатывает, когда указатель мыши находится в области экрана, занимаемой элементом
mouseup() Соответствует событию mouseup, которое срабатывает при отпускании ранее нажатой кнопки мыши над элементом
События формы
blur() Соответствует событию blur, которое срабатывает, когда элемент теряет фокус
change() Соответствует событию change, которое срабатывает при изменении значения элемента
focus() Соответствует событию focus, которое срабатывает, когда элемент получает фокус
select() Соответствует событию select, которое срабатывает при выборе пользователем значения элемента
submit() Соответствует событию submit, которое срабатывает при отправке формы пользователем
События клавиатуры
keydown() Соответствует событию keydown, которое срабатывает, когда пользователь нажимает клавишу на клавиатуре
keypress() Соответствует событию keypress, которое происходит, когда пользователь нажимает и отпускает клавишу на клавиатуре
keyup() Соответствует событию keyup, которое срабатывает, когда пользователь отпускает клавишу на клавиатуре

Метод ready() заслуживает отдельного замечания. Ему нет соответствия среди событий DOM, но он чрезвычайно полезен при работе с jQuery.

Метод hover() предлагает удобный способ связывания функции-обработчика с событиями mouseenter и mouseleave. Если функции передаются два аргумента, то первый из них вызывается в ответ на событие mouseenter, а второй — в ответ на событие mouseleave. Если вы укажете только одну функцию, то она будет вызываться для обоих событий. Пример использования метода hover() представлен в примере ниже:

Клавиатура: keydown и keyup

Прежде чем перейти к клавиатуре, обратите внимание, что на современных устройствах есть и другие способы «ввести что-то». Например, распознавание речи (это особенно актуально на мобильных устройствах) или Копировать/Вставить с помощью мыши.

Поэтому, если мы хотим корректно отслеживать ввод в поле , то одних клавиатурных событий недостаточно. Существует специальное событие input , чтобы отслеживать любые изменения в поле . И оно справляется с такой задачей намного лучше. Мы рассмотрим его позже в главе События: change, input, cut, copy, paste.

События клавиатуры же должны использоваться, если мы хотим обрабатывать взаимодействие пользователя именно с клавиатурой (в том числе виртуальной). К примеру, если нам нужно реагировать на стрелочные клавиши Up и Down или горячие клавиши (включая комбинации клавиш).

Тестовый стенд

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

Сфокусируйтесь на поле и нажмите какую-нибудь клавишу.

События keydown и keyup

Событие keydown происходит при нажатии клавиши, а keyup – при отпускании.

event.code и event.key

Свойство key объекта события позволяет получить символ, а свойство code – «физический код клавиши».

К примеру, одну и ту же клавишу Z можно нажать с клавишей Shift и без неё. В результе получится два разных символа: z в нижнем регистре и Z в верхнем регистре.

Свойство event.key – это непосредственно символ, и он может различаться. Но event.code всегда будет тот же:

Клавиша event.key event.code
Z z (нижний регистр) KeyZ
Shift + Z Z (Верхний регистр) KeyZ

Если пользователь работает с разными языками, то при переключении на другой язык символ изменится с «Z» на совершенно другой. Получившееся станет новым значением event.key , тогда как event.code останется тем же: «KeyZ» .

У каждой клавиши есть код, который зависит от её расположения на клавиатуре. Подробно о клавишных кодах можно прочитать в спецификации о кодах событий UI.

  • Буквенные клавиши имеют коды по типу «Key » : «KeyA» , «KeyB» и т.д.
  • Коды числовых клавиш строятся по принципу: «Digit » : «Digit0» , «Digit1» и т.д.
  • Код специальных клавиш – это их имя: «Enter» , «Backspace» , «Tab» и т.д.

Существует несколько широко распространённых раскладок клавиатуры, и в спецификации приведены клавишные коды к каждой из них.

Можно их прочитать в разделе спецификации, посвящённом буквенно-цифровым клавишам или просто нажмите нужную клавишу на тестовом стенде выше и посмотрите.

Выглядит очевидно, но многие всё равно ошибаются.

Пожалуйста, избегайте опечаток: правильно KeyZ , а не keyZ . Условие event.code==»keyZ» работать не будет: первая буква в слове «Key» должна быть заглавная.

А что, если клавиша не буквенно-цифровая? Например, Shift или F1 , или какая-либо другая специальная клавиша? В таких случаях значение свойства event.key примерно тоже, что и у event.code :

Клавиша event.key event.code
F1 F1 F1
Backspace Backspace Backspace
Shift Shift ShiftRight или ShiftLeft

Обратите внимание, что event.code точно указывает, какая именно клавиша нажата. Так, большинство клавиатур имеют по две клавиши Shift : слева и справа. event.code уточняет, какая именно из них была нажата, в то время как event.key сообщает о «смысле» клавиши: что вообще было нажато ( Shift ).

Допустим, мы хотим обработать горячую клавишу Ctrl + Z (или Cmd + Z для Mac). Большинство текстовых редакторов к этой комбинации подключают действие «Отменить». Мы можем поставить обработчик событий на keydown и проверять, какая клавиша была нажата.

Здесь возникает дилемма: в нашем обработчике стоит проверять значение event.key или event.code ?

С одной стороны, значение event.key – это символ, он изменяется в зависимости от языка, и если у пользователя установлено в ОС несколько языков, и он переключается между ними, нажатие на одну и ту же клавишу будет давать разные символы. Так что имеет смысл проверять event.code , ведь его значение всегда одно и тоже.

Вот пример кода:

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

Например, вот схема стандартной (US) раскладки («QWERTY») и под ней немецкой («QWERTZ») раскладки (из Википедии):

Для одной и той же клавиши в американской раскладке значение event.code равно «Z», в то время как в немецкой «Y».

Буквально, для пользователей с немецкой раскладкой event.code при нажатии на Y будет равен KeyZ .

Если мы будем проверять в нашем коде event.code == ‘KeyZ’ , то для людей с немецкой раскладкой такая проверка сработает, когда они нажимают Y .

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

Так что event.code может содержать неправильный символ при неожиданной раскладке. Одни и те же буквы на разных раскладках могут сопоставляться с разными физическими клавишами, что приводит к разным кодам. К счастью, это происходит не со всеми кодами, а с несколькими, например KeyA , KeyQ , KeyZ (как мы уже видели), и не происходит со специальными клавишами, такими как Shift . Вы можете найти полный список проблемных кодов в спецификации.

Чтобы отслеживать символы, зависящие от раскладки, event.key надёжнее.

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

Хотим поддерживать клавиши, меняющиеся при раскладке? Тогда event.key – верный выбор.

Или мы хотим, чтобы горячая клавиша срабатывала даже после переключения на другой язык? Тогда event.code может быть лучше.

Автоповтор

При долгом нажатии клавиши возникает автоповтор: keydown срабатывает снова и снова, и когда клавишу отпускают, то отрабатывает keyup . Так что ситуация, когда много keydown и один keyup , абсолютно нормальна.

Для событий, вызванных автоповтором, у объекта события свойство event.repeat равно true .

Действия по умолчанию

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

  • Появление символа (самое очевидное).
  • Удаление символа (клавиша Delete ).
  • Прокрутка страницы (клавиша PageDown ).
  • Открытие диалогового окна браузера «Сохранить» ( Ctrl + S )
  • …и так далее.

Предотвращение стандартного действия с помощью event.preventDefault() работает практически во всех сценариях, кроме тех, которые происходят на уровне операционной системы. Например, комбинация Alt + F4 инициирует закрытие браузера в Windows, что бы мы ни делали в JavaScript.

Для примера, ниже ожидает телефонный номер, так что ничего кроме чисел, + , () или — принято не будет:

Заметьте, что специальные клавиши, такие как Backspace , Left , Right , Ctrl + V , в этом поле для ввода не работают. Это побочный эффект чересчур жёсткого фильтра checkPhoneKey .

Добавим ему немного больше свободы:

Теперь стрелочки и удаление прекрасно работают.

…Впрочем, мы всё равно можем ввести в что угодно с помощью правого клика мыши и пункта «Вставить» контекстного меню. Так что такой фильтр не обладает 100% надёжностью. Мы можем просто оставить всё как есть, потому что в большинстве случаев это работает. Альтернатива – отслеживать событие input , оно генерируется после любых изменений в поле , и мы можем проверять новое значение и подчёркивать/изменять его, если оно не подходит.

«Дела минувших дней»

В прошлом существовало также событие keypress , а также свойства keyCode , charCode , which у объекта события.

Но количество браузерных несовместимостей при работе с ними было столь велико, что у разработчиков спецификации не было другого выхода, кроме как объявить их устаревшими и создать новые, современные события (которые и описываются в этой главе). Старый код ещё работает, так как браузеры продолжают поддерживать и keypress , и keyCode с charCode , и which , но более нет никакой необходимости в их использовании.

Итого

Нажатие клавиши всегда генерирует клавиатурное событие, будь то буквенно-цифровая клавиша или специальная типа Shift или Ctrl и т.д. Единственным исключением является клавиша Fn , которая присутствует на клавиатуре некоторых ноутбуков. События на клавиатуре для неё нет, потому что она обычно работает на уровне более низком, чем даже ОС.

  • keydown – при нажатии на клавишу (если клавиша остаётся нажатой, происходит автоповтор),
  • keyup – при отпускании клавиши.

Главные свойства для работы с клавиатурными событиями:

  • code – «код клавиши» ( «KeyA» , «ArrowLeft» и так далее), особый код, привязанный к физическому расположению клавиши на клавиатуре.
  • key – символ ( «A» , «a» и так далее), для не буквенно-цифровых групп клавиш (таких как Esc ) обычно имеет то же значение, что и code .

В прошлом события клавиатуры иногда использовались для отслеживания ввода данных пользователем в полях формы. Это ненадёжно, потому как ввод данных не обязательно может осуществляться с помощью клавиатуры. Существуют события input и change специально для обработки ввода (рассмотренные позже в главе События: change, input, cut, copy, paste). Они срабатывают в результате любого ввода, включая Копировать/Вставить мышью и распознавание речи.

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

Задачи

Отследить одновременное нажатие

Создайте функцию runOnKeys(func, code1, code2, . code_n) , которая запускает func при одновременном нажатии клавиш с кодами code1 , code2 , …, code_n .

Например, код ниже выведет alert при одновременном нажатии клавиш «Q» и «W» (в любом регистре, в любой раскладке)

Необходимо использовать два обработчика событий: document.onkeydown и document.onkeyup .

Создадим множество pressed = new Set() , в которое будем записывать клавиши, нажатые в данный момент.

В первом обработчике будем добавлять в него значения, а во втором удалять. Каждый раз, как отрабатывает keydown , будем проверять – все ли нужные клавиши нажаты, и, если да – выводить сообщение.

Действие по нажатию клавиши в JQuery

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

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

keyup — Устанавливает обработчик возвращения клавиши клавиатуры в ненажатое состояние, либо, запускает это событие. Работает с английской и русской раскладкой клавиатуры одинаково!

keydown — устанавливает обработчик перехода клавиши клавиатуры в нажатое состояние, либо, запускает это событие. Работает с английской и русской раскладкой клавиатуры одинаково!

keypress — Не очень. Работает только с одной раскладкой

Теперь рассмотрим 3 примера:

Скачать готовый пример, который визуально отобразит нажатие клавиш в вашем браузере

Во всех примерах запускается действие плавного выдвижения панели. Таблица соответствия JQuery для нажатых клавиш при методе keyup() и keydown() представлена ниже. Код нужной клавише находится только в столбике Dec! (Клавиша Ctrl – 17):

jQuery для начинающих. Часть 6. События // JavaScript

Прежде чем приступить к прочтению данной статьи, стоит определиться, что из себя представляют события — для web-странички, событиями будут являться любые действия пользователя – это и ввод данных с клавиатуры, и передвижения мышки, и конечно же “клики” – всё это и есть события. К событиям можно еще отнести события создаваемые скриптами, т.н. триггеры.

Материалы данной статьи включены в учебник «jQuery для начинающих». Учебник распространяется бесплатно, и сопровождается интерактивными примерами.

Базовые события

Начнем с азов. jQuery работает практически со всеми событиями в JavaScript’е, приведу список функции с небольшими пояснениями:

  • change — измение значения элемента (значение, при потери фокуса, элемента отличается от изначального, при получении фокуса)
  • click — клик по элементу (порядок событий — mousedown, mouseup, click)
  • dblclick — двойной клик по элементу
  • resize — изменение размеров элементов
  • scroll – скроллинг элемента
  • select — выбор текста (актуален только для input[type=text] и textarea)
  • submit — отправка формы
  • focus — фокус на элементе – актуально для input[type=text], но в современных браузерах работает и с другими элементами
  • blur — фокус ушел с элемента – актуально для input[type=text] — срабатывает при клике по другому элементу на странице или по событию клавиатуры (к примеру переключение по tab’у)
  • focusin — фокус на элементе, данное событие срабатывает на предке элемента, для которого произошло событие focus
  • focusout — фокус ушел с элемента, данное событие срабатывает на предке элемента, для которого произошло событие blur
  • keydown — нажатие клавиши на клавиатуре
  • keypress — нажатие клавиши на клавиатуре (порядок событий — keydown, keypress, keyup)
  • keyup — отжатие клавиши на клавиатуре
  • load — загрузка элемента (img)
  • unload — выгрузка элемента (window)
  • mousedown — нажатие клавиши мыши
  • mouseup — отжатие клавиши мыши
  • mousemove — движение курсора
  • mouseenter — наведение курсора на элемент, не срабатывает при переходе фокуса на дочерние элементы
  • mouseleave — вывод курсора из элемента, не срабатывает при переходе фокуса на дочерние элементы
  • mouseover — наведение курсора на элемент
  • mouseout — вывод курсора из элемента

Опробовать события можно на примере с событиями мышки и элементами формы.

Большинство из перечисленных событий можно имитировать непосредственно из самого скрипта:

Триггеры

Для работы с триггерами в jQuery предопределены следующие функции:

  • bind (type, data, fnc) — добавляет обработчик событий
  • one (type, data, fnc) — добавляет обработчик событий, который сработает лишь раз
  • trigger (event, data) — вызывает обработчики событий
  • triggerHandler( event, data) — вызывает обработчики событий, без вызова события браузера
  • unbind (type, fnc) — удаляет все обработчики событий с элемента

Можно повесить триггер почти на любой объект:

Пространство имен

Обычно, когда мы хотим создать/удалить свой обработчик событий, мы пишем следующий код (чуть выше я об этом уже писал):

Но как всегда, есть ситуации когда нам необходимо отключить не все обработчики (как пример, надо отключить обработку какого-то контрола определенным плагином), в этом случае нам на помощь приходят пространства имен, использовать их достаточно легко:

Еще примерчик, вешаем обработчик, который выводит текст в консоль.

Так же, есть поддержка нескольких пространств имен (с версии 1.3, если быть точным):

Можно одним махом удалить все обработчики с определенного пространства имен:

Работа с live

Очень часто при генерации страниц AJAX’ом возникает необходимость повесить обработчики событий на новые элементы в DOMе, для этой цели служит метод live (первый параметр — имя события, второй — обработчик).

Приведу пример — есть следующая задача:

    все внутренние ссылки на страницы должны подгружать контент AJAXом в элемент с >Реализовать первое требование достаточно просто:

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

Поддерживаемые события: click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, keydown, keypress, keyup, change, submit, focusin, focusout, mouseenter, mouseleave
Нет поддержки: blur, focus, change, submit

В противовес функции live существует функция die — она убирает отслеживание событий для вновь появившихся элементов.

Хотелось бы отдельно остановиться на принципе работы метода live — данный метод работает благодаря т.н. «всплытию» событий в DOMе — т.е. когда вы кликаете на любом элементе на странице, то в первую очередь событие сработает на этом элементе, если обработчика события нет, или он не говорит, что дальше «всплывать» не надо (сказать он это может так event.stopPropagation()), то событие идет вверх по DOM дереву и инициализирует обработчики у родительского элемента, и так далее пока не достигнет корня — document’a. Таким образом метод live вешает обработчик событий на document, и затем анализирует каждое событие на предмет наличия элементов описанных вами. Это конечно не самый быстрый способ, но его можно ускорить используя метод delegate, его отличие от live только в том, что вы указываете элемент на который вешаете обработчик «live» событий, таким образом пример выше можно записать так:

Touch события

Смартфоны с большим сенсорным экраном — это уже не редкость, вот и web-индустрия начинает адаптироваться под пользователей того же iPhone, если же вам понадобилось подобная адаптация, то вам пригодится следующая информация:

События в JavaScript’е:

  • touchstart — аналогично mousedown
  • touchmove — mousemove
  • touchend — mouseup
  • touchcancel — аналогии нет

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

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

Некоторые программы с применением JavaScript event работают напрямую с вводимыми пользователем данными. Момент возникновения и порядок таких взаимодействий не могут быть предсказаны заранее.

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

Реагировать на нажатие клавиши можно, постоянно считывая ее состояние, чтобы поймать момент нажатия клавиши, прежде чем она снова не будет отпущена.

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

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

Большинство программистов стараются избегать его, если это возможно.

Самым лучшим способом считается реализация системы, которая дает коду возможность реагировать на события, когда они происходят. Браузеры реализуют ее, предоставляя возможность регистрировать функции обработчиков для конкретных JavaScript event :

Функция addEventListener регистрируется таким образом, что ее второй аргумент вызывается всякий раз, когда происходит событие, описанное первым аргументом.

События и узлы DOM

Каждый обработчик событий браузера регистрируется в контексте. При вызове функции addEventListener она вызывается как метод для всего окна, так как в браузере глобальный диапазон эквивалентен объекту window . Каждый элемент DOM имеет свой собственный метод addEventListener , который позволяет отслеживать события именно в этом элементе:

В данном примере обработчик подключен к узлу кнопки. JavaScript mouse events приводит в действие обработчик, а клик в остальной части документа — нет.

Установив для узла атрибут onclick , мы получим тот же результат. Но узел имеет только один атрибут onclick , поэтому можно зарегистрировать для каждого узла только один обработчик. Метод addEventListener позволяет добавлять любое количество обработчиков. Так мы застрахованы от случайной замены обработчика, который уже был зарегистрирован.

Метод removeEventListener , вызывается с аргументами, аналогичными addEventListener . Он удаляет обработчик:

Чтобы отменить функцию обработчика, мы задаем для нее имя ( например, once ). Так мы передаем ее как в addEventListener , так и в removeEventListener .

Объекты событий

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

Информация, хранящаяся в объекте, различается зависимости от типа события. Свойство объекта type всегда содержит строку, идентифицирующую событие (например, « click » или « mousedown «).

Распространение

Обработчики событий ( например, JavaScript touch events ), зарегистрированные для родительских узлов, также будут принимать события, которые происходят в дочерних элементах. Если была нажата кнопка, находящаяся внутри абзаца, обработчики событий абзаца также получат событие click .

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

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

В следующем примере мы регистрируем обработчики « MouseDown » как для кнопки, так и для абзаца. При клике правой клавишей ( JavaScript mouse events ) обработчик вызывает метод stopPropagation , который предотвращает запуск обработчика абзаца. При нажатии на кнопку другой клавишей мыши запускаются оба обработчика:

Большинство объектов событий имеют свойство target , которое указывает на узел, в котором они возникли. Вы можете использовать это свойство, чтобы случайно не обрабатывать какое-то событие, которое распространяется вверх из узла.

Также можно использовать JavaScript event target , чтобы расширить диапазон события определенного типа. Например, если у вас есть узел, содержащий длинный список кнопок, более удобно зарегистрировать один обработчик клика для внешнего узла и использовать свойство target , чтобы отслеживать, была ли нажата кнопка, а не регистрировать экземпляры обработчика для всех кнопок:

Действия по умолчанию

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

Для большинства типов событий обработчики JavaScript event вызываются до выполнения действий по умолчанию. Если не нужно, чтобы выполнялось поведение по умолчанию, нужно вызвать для объекта события метод preventDefault .

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

Старайтесь не делать так, если у вас нет на это веских причин.

В зависимости от браузера некоторые события не могут быть перехвачены. В Google Chrome , например, сочетание клавиш ( event keycode JavaScript ) для закрытия текущей вкладки ( Ctrl-W или Command-W ) не может быть обработано с помощью JavaScript .

События клавиш

Когда пользователь нажимает клавишу на клавиатуре, браузер запускает событие « keydown «. Когда он отпускает клавишу, срабатывает событие « keyup «:

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

В предыдущем примере использовано свойство объекта event keycode JavaScript . С его помощью определяется, какая именно клавиша была нажата или отпущена. Ноне всегда очевидно, как привести числовой код клавиши к фактической клавише.

Для считывания значений клавиш букв и цифр используется код символа Unicode . Он связан с буквой ( в верхнем регистре ) или цифрой, обозначенной на клавише. Метод charCodeAt для строк позволяет получить это значение:

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

Такие клавиши, как Shift , Ctrl , Alt порождают события, как обычные клавиши. Но при отслеживании комбинаций клавиш также можно определить, нажаты ли эти клавиши, по свойствам событий клавиатуры и JavaScript mouse events : shiftKey , ctrlKey , altKey и metaKey :

События « keydown » и « keyup » предоставляют информацию о фактическом нажатии клавиш. Но что, если нам нужен сам вводимый текст? Получать текст из кодов клавиш неудобно. Для этого существует событие, « keypress «, которое срабатывает сразу после « keydown «. Оно повторяется вместе с « keydown «, пока клавиша нажата. Но только для клавиш, с помощью которых производится ввод символов.

Свойство charCode в объекте события содержит код, который может быть интерпретирован, как код символа Unicode . Мы можем использовать функцию String.fromCharCode , чтобы преобразовать этот код в строку из одного символа.

Узел DOM , в котором происходит событие зависит, от того элемента, который находился в фокусе ввода при нажатии клавиши. Обычные узлы не могут находиться в фокусе ввода ( если не установить для них атрибут tabindex ), но такие элементы, как ссылки, кнопки и поля формы, могут.

Если никакой конкретный элемент не выделен фокусом ввода, то в качестве целевого узла для событий клавиши и JavaScript touch events выступает document.body .

Клики мыши

Нажатие клавиши мыши также приводит в действие ряд событий. События « mousedown » и « mouseup » похожи на « keydown » и « keyup «. Они запускаются, когда нажата и отпущена клавиша мыши. Данные события возникают в узлах DOM, на которые был наведен указатель мыши, когда возникло событие.

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

Если два клика возникли близко друг к другу, также запускается событие « dblclick » ( двойной клик ). Оно возникает после второго клика. Чтобы получить точную информацию о месте, где произошло событие мыши, нужно получить значение свойств pageX и pageY , которые содержат координаты события ( в пикселях ) относительно левого верхнего угла документа.

Ниже приведена реализация примитивной программы для рисования. Каждый раз при нажатии мыши в документе ( под курсором ) добавляется точка:

Свойства clientX и clientY подобны pageX и pageY , но они относятся к видимой части документа. Они могут использоваться для сравнения координат мыши с координатами, возвращаемыми функцией getBoundingClientRect .

Движение мыши

Каждый раз, когда перемещается курсов мыши, срабатывает событие « mousemove » из набора JavaScript mouse events . Оно может быть использовано для отслеживания положения мыши. Это применяется при реализации возможности перетаскивания элементов мышью.

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

Обратите внимание, что обработчик « mousemove » зарегистрирован для всего окна. Даже если во время изменения размеров мышь выходит за пределы панели, мы все равно обновляем ширину панели и прекращаем JavaScript touch events , когда клавиша мыши была отпущена.

Мы должны прекратить изменение размера панели, когда пользователь отпускает клавишу мыши. К сожалению, не все браузеры устанавливают для событий « mousemove » свойство which . Существует стандартное свойство buttons , которое предоставляет аналогичную информацию, но оно также поддерживается не во всех браузерах. К счастью, все основные браузеры поддерживают что-то одно: либо buttons , либо which . Функция buttonPressed в приведенном выше примере сначала пытается использовать свойство buttons , и, если оно не доступно, переходит к which .

Когда курсор мыши наводится или покидает узел, запускаются события « mouseover » или « mouseout «. Они могут использоваться для создания эффектов при наведении курсора мыши, вывода какой-нибудь подписи или изменения стиля элемента.

Чтобы создать такой эффект, недостаточно просто начать его отображение при возникновении события « mouseover » и завершить после события « mouseout «. Когда мышь перемещается от узла к одному из его дочерних элементов, для родительского узла происходит событие « mouseout «. Хотя указатель мыши не покинул диапазон распространения узла.

Что еще хуже, эти JavaScript event распространяются так же, как и другие события. Когда мышь покидает один из дочерних узлов, для которого зарегистрирован обработчик, возникнет событие « mouseout «.

Чтобы обойти эту проблему, можно использовать свойство объекта события relatedTarget . В случае возникновения события « mouseover » оно указывает, на какой элемент был наведен курсор мыши до этого. А в случае возникновения « mouseout » — к какому элементу перемещается указатель. Мы будем изменять эффект наведения мыши только, когда relatedTarget находится вне нашего целевого узла.

В этом случае мы изменяем поведение, потому что курсор мыши был наведен на узел из-за его пределов ( или наоборот ):

Функция isInside отслеживает родительские связи заданного узла или пока не будет достигнута верхняя часть документа ( когда node равен нулю ). Либо не будет найден родительский элемент, который нам нужен.

Эффект наведения гораздо проще создать с помощью псевдоселектора CSS :hover , как показано в следующем примере. Но когда эффект наведения предполагает что-то более сложное, чем просто изменение стиля целевого узла, тогда нужно использовать прием с использованием событий « mouseover » и « mouseout » ( JavaScript mouse events ):

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


Каждый раз, когда элемент прокручивается, в нем срабатывает JavaScript scroll event . Его можно использовать для отслеживания того, что в данный момент просматривает пользователь; для отключения анимации, расположенной вне окна просмотра.

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

Установив для элемента свойство position или fixed , мы получим тот же результат, что и при установке position:absolute . Но так мы также блокируем прокрутку элемента вместе с остальной частью документа. В результате индикатор прогресса будет статически закреплен в верхнем углу. Внутри него находится еще один элемент, размер которого изменяется в соответствии с текущим прогрессом.

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

Глобальная переменная innerHeight содержит высоту окна, которую мы должны вычесть из общей доступной прокручиваемой высоты документа. Нельзя прокручивать окно ниже при достижении нижней части документа. С innerHeight также может использоваться innerWidth . Разделив pageYOffset ( текущую позицию окна прокрутки ) на максимально допустимую позицию прокрутки и умножив на 100, мы получаем процент для индикатора прогресса.

Вызов preventDefault для JavaScript scroll event не предотвращает прокрутку. Обработчик события вызывается только после того, как происходит прокручивание.

События фокуса ввода

Когда элемент находится в фокусе ввода, браузер запускает в нем событие « focus «. Когда фокус ввода снимается, запускается событие « blur «.

Эти два события не имеют распространения. Обработчик родительского элемента не уведомляется, когда дочерний элемент выделяется фокусом ввода.

В следующем примере выводится подсказка для текстового поля, которое в данный момент находится в фокусе ввода:

Объект окна получает события « focus » и « blur «, когда пользователь переходит или покидает вкладку, окно браузера, в котором выводится документ.

Событие загрузки

Когда завершается загрузка страницы, для объектов тела документа и окна возникает JavaScript event «load» . Оно используется для планирования инициализации действий, для которых требуется загрузка всего документа. Не забывайте, что содержимое

Иногда нужно отменить функцию, которую мы запланировали. Это делается путем сохранения значения, возвращаемого функцией setTimeout , и вызова для нее clearTimeout :

Функция cancelAnimationFrame работает так же, как clearTimeout . Она вызывается значением, возвращаемым requestAnimationFrame , чтобы отменить кадр ( если он еще не был вызван ).

Похожий набор функций, setInterval и clearInterval используется для установки таймера, который должен повторять действие каждые X миллисекунд:

Дробление

Некоторые типы событий могут запускаться много раз в течение короткого периода времени ( например, « mousemove » и javascript scroll event ). При обработке таких событий, нужно быть осторожным, чтобы это не происходило очень долго, иначе обработчик будет выполнять действие столько времени, что взаимодействие с документом станет медленным и скачкообразным.

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

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

Передача неопределенного значения для clearTimeout или его вызов для задержки, которая уже запущена, не даст никакого результата. Нам больше не нужно быть осторожными относительно того, когда его вызывать, мы просто делаем это для каждого события.

Можно использовать иной сценарий, если нужно разделить ответы небольшим промежутком времени. Но чтобы при этом они запускались во время серии событий, а не только после нее. Например, можно отправлять в ответ на события « mousemove » ( JavaScript mouse events ) текущие координаты мыши, но только через каждые 250 миллисекунд:

Заключение

Обработчики событий позволяют обнаруживать и реагировать на события, над которыми мы не имеем прямого контроля. Для регистрации такого обработчика используется метод addEventListener .

Каждое событие относится к определенному типу (« keydown «, « focus » и так далее ), который идентифицирует его. Большинство событий вызывается для конкретного элемента DOM , а затем распространяются на родительские узлы элемента. Это позволяет обработчикам, связанным с этими элементами, обрабатывать их.

Когда вызывается обработчик, ему передается объект события с дополнительной информацией о действии. Этот объект также содержит методы, позволяющие остановить дальнейшее распространение события ( stopPropagation ) или предотвратить обработку события браузером по умолчанию ( preventDefault ).

Нажатие клавиш порождает события « keydown «, « keypress » и « keyup «. Нажатие мыши порождает события « mousedown «, « mouseup » и « click «. Перемещение мыши — « mousemove «, « mouseenter » и « mouseout «.

JavaScript scroll event можно определить с помощью события « scroll «, а смена фокуса — « focus » и « blur «. После завершения загрузки документа для окна возникает событие « load «.

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

Данная публикация представляет собой перевод статьи « Handling Events » , подготовленной дружной командой проекта Интернет-технологии.ру

Все о WEB программировании

WEB программирование от А до Я

Заказать сайт:

Социальные сети:

Партнеры:

Изучаем jQuery. Часть 8.2 События

Доброго времени суток. Мы продолжаем изучать jQuery, а точнее события в jQuery. Так мы с Вами уже рассмотрели события связанные с мышкой « Изучаем jQuery. Часть 8.1 События ». А в этой статье мы остановимся событиях связанных с клавиатурой.

jQuery у нас подключен к проекту, если Вы не знаете как это сделать, то Вам поможет статья « Изучаем jQuery. Часть 1. Подключение jQuery ». Ну, что ж приступим.

И первое событие, которое связано с клавиатурой — это событие нажатой клавиши.

Событие keydown()

Событие keydown() возникает в момент когда нажата (но не отпущена) клавиша на клавиатуре.

Рассмотрим следующий html-код:

Теперь, когда в поле input с >

Для этого в наш файл со скриптами добавим следующий код:

Давайте посмотрим, что получилось.

Событие keyup()

Событие keyup() возникает, когда нажатая клавиша на клавиатуре отпущена.

Рассмотрим выше приведенный html-код. Теперь, когда мы отпускаем клавишу на клавиатуре в поле input с >

Смотрим, что получилось.

Событие keypress()

Событие keypress() возникает, когда мы вводим символ с клавиатуры.

Рассмотрим html-код приведенный выше. Теперь мы хотим, чтобы вводе в input с >

Мы с Вами разобрали три основных события jQuery, которые возникают при работе с клавиатурой.

Выразительный JavaScript: Обработка событий

Содержание

Вы властны над своим разумом, но не над внешними событиями. Когда вы поймёте это, вы обретёте силу.
Марк Аврелий, «Медитации».

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

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

Представьте интерфейс, в котором единственным способом узнать, нажали ли на кнопку клавиатуры, было бы считывание текущего состояния кнопки. Чтобы реагировать на нажатия, вам пришлось бы постоянно считывать состояния кнопок, чтобы вы могли поймать это состояние, пока кнопка не отжалась. Было бы опасно проводить другие подсчёты, отнимающие процессорное время, так как можно было бы пропустить момент нажатия.

Таким образом ввод обрабатывался на примитивных устройствах. Шагом вперёд было бы, если железо или операционка замечали бы нажатие кнопки и передавали бы его в очередь. Затем программа периодически могла бы проверять очередь на новые события и реагировать на то, что находится в очереди.

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

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

Функция addEventListener регистрирует свой второй аргумент как функцию, которая вызывается, когда описанное в первом аргументе событие случается.

События и узлы DOM

Каждый обработчик событий браузера зарегистрирован в контексте. Когда вы вызываете addEventListener, вы вызываете её как метод целого окна, потому что в браузере глобальная область видимости – это объект window. У каждого элемента DOM есть свой метод addEventListener, позволяющий слушать события от этого элемента.

Пример назначает обработчик на DOM-узел кнопки. Нажатия на кнопку запускают обработчик, а нажатия на другие части документа – не запускают.

Присвоение узлу атрибута onclick работает похоже. Но у узла есть только один атрибут onclick, значит таким способом вы можете зарегистрировать только один обработчик. Метод addEventListener позволяет добавлять любое количество обработчиков, так что вы не замените случайно уже назначенный ранее обработчик.

Метод removeEventListener, вызванный с такими же аргументами, как addEventListener, удаляет обработчик.

Чтобы это провернуть, мы даём функции имя (в данном случае, once), чтобы её можно было передать и в addEventListener, и в removeEventListener.

Объекты событий

В примерах мы проигнорировали тот факт, что функциям-обработчикам передаётся аргумент – объект события. В нём хранится дополнительная информация о событии. К примеру, если надо узнать, какая кнопка мыши была нажата, мы можем обратиться к свойству which этого объекта.

Хранящаяся в объекте информация – разная для каждого типа событий. Мы обсудим эти типы позже. Свойство объекта type всегда содержит строку, описывающую событие (например, «click» или «mousedown»).

Распространение (propagation)

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

Если и у параграфа и у кнопки есть обработчики, то первым запустится более конкретный – то есть, обработчик кнопки. Событие как бы распространяется наружу, от узла, где оно случилось, до его родительского и далее до корня документа. После отработки всех обработчиков всех промежуточных узлов, очередь среагировать на событие доходит и до самого окна.

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

Следующий пример регистрирует обработчики «mousedown» как на кнопке, так и на окружающем параграфе. При щелчке правой кнопкой обработчик кнопки вызывает stopPropagation, который предотвращает запуск обработчика параграфа. При клике другой кнопкой запускаются оба обработчика.

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

Также возможно использовать свойство target, чтобы распространить обработку конкретного типа события. К примеру, если у вас есть узел, содержащий длинный список кнопок, было бы удобнее зарегистрировать один обработчик событий для узла, и в нём выяснять, нажали ли на кнопку – вместо того, чтобы регистрировать обработчики каждой кнопки по отдельности.

Действия по умолчанию

У многих событий есть действия по умолчанию. При клике на ссылку вы перейдёте по ней. При нажатии на стрелку вниз браузер прокрутит страницу вниз. По правому клику мыши вы увидите контекстное меню. И так далее.

Для большинства типов событий обработчики событий вызываются до того, как сработает действие по умолчанию. Если обработчик не хочет, чтобы это действие происходило (часто потому, что он уже обработал его), он может вызвать метод preventDefault объекта события.

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

Не делайте так – если у вас нет очень серьёзной причины! Пользователям вашей страницы будет очень неудобно, когда они столкнутся с неожиданными результатами своих действий. В зависимости от браузера, некоторые события перехватить нельзя. В Chrome нельзя обрабатывать горячие клавиши закрытия текущей закладки (Ctrl-W or Command-W).

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

При нажатии кнопки на клавиатуре браузер запускает событие «keydown». Когда она отпускается, происходит событие «keyup».

Несмотря на название, «keydown» происходит не только тогда, когда на кнопку нажимают. Если нажать и удерживать кнопку, событие будет происходить каждый раз по приходу повторного сигнала от клавиши (key repeat). Если вам, к примеру, надо увеличивать скорость игрового персонажа, когда нажата кнопка со стрелкой, и уменьшать её, когда она отпущена – надо быть осторожным, чтобы не увеличить скорость каждый раз при повторе сигнала от кнопки, иначе скорость возрастёт очень сильно.

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

Для цифр и букв код будет кодом символа Unicode, связанного с прописным символом, изображённым на кнопке. Метод строки charCodeAt даёт нам этот код.

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

Кнопки-модификаторы типа Shift, Ctrl, Alt, и Meta (Command на Mac) создают события, как и нормальные кнопки. Но при разборе комбинаций клавиш можно выяснить, были ли нажаты модификаторы, через свойства shiftKey, ctrlKey, altKey, и metaKey событий клавиатуры и мыши.

События «keydown» и «keyup» дают информацию о физическом нажатии кнопок. А если вам нужно узнать, какой текст вводит пользователь? Создавать его из нажатий кнопок – неудобно. Для этого существует событие «keypress», происходящее сразу после «keydown» (и повторяющееся вместе с «keydown», если клавишу продолжают удерживать), но только для тех кнопок, которые выдают символы. Свойство объекта события charCode содержит код, который можно интерпретировать как код Unicode. Мы можем использовать функцию String.fromCharCode для превращения кода в строку из одного символа.

Источником события нажатия клавиши узел становится в зависимости от того, где находился фокус ввода во время нажатия. Обычные узлы не могут получить фокус ввода (если только вы не задали им атрибут tabindex), а такие, как ссылки, кнопки и поля форм – могут. Мы вернёся к полям ввода в главе 18. Когда ни у чего нет фокуса, в качестве целевого узла событий работает document.body

Кнопки мыши

Нажатие кнопки мыши тоже запускает несколько событий. События «mousedown» и «mouseup» похожи на «keydown» и «keyup», и запускаются, когда кнопка нажата и когда отпущена. События происходят у тех узлов DOM, над которыми находился курсор мыши.

После события «mouseup» на узле, на который пришлись и нажатие, и отпускание кнопки, запускается событие “click”. Например, если я нажал кнопку над одним параграфом, потом передвинул мышь на другой параграф и отпустил кнопку, событие “click” случится у элемента, который содержал в себе оба эти параграфа.

Если два щелка происходят достаточно быстро друг за другом, запускается событие «dblclick» (double-click), сразу после второго запуска “click”.

Для получения точных координат места, где произошло событие мыши, обратитесь к свойствам pageX и pageY – они содержат координаты в пикселях относительно верхнего левого угла.

В примере создана примитивная программа для рисования. Каждый раз по клику на документе он добавляет точку под вашим курсором. В главе 19 будет представлена менее примитивная программа для рисования.

Свойства clientX и clientY похожи на pageX и pageY, но дают координаты относительно части документа, которая видна сейчас (если документ был прокручен). Это удобно при сравнении координат мыши с координатами, которые возвращает getBoundingClientRect – его возврат тоже связан с относительными координатами видимой части документа.

Движение мыши

Каждый раз при сдвиге курсора мыши запускается событие «mousemove». Его можно использовать для отслеживания позиции мыши. Обычно это нужно при создании некоей функциональности, связанной с перетаскиванием объектов мышью.

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

Обратите внимание – обработчик «mousemove» зарегистрирован у всего окна. Даже если мышь уходит за пределы полоски, нам надо обновлять её размер и прекращать это, когда кнопку отпускают.

Когда курсор попадает на узел и уходит с него, происходят события «mouseover» or «mouseout». Их можно использовать, кроме прочего, для создания эффектов проведения мыши, показывая или меняя стиль чего-либо, когда курсор находится над этим элементом.

К сожалению, создание такого эффекта не ограничивается запуском его при событии «mouseover» и завершением при событии «mouseout». При движении мыши от узла к его дочерним узлам на родительском узле происходит событие «mouseout», хотя мышь, вообще говоря, его и не покидала. Что ещё хуже, эти события распространяются как и все другие, поэтому вы всё равно получаете «mouseout» при уходе курсора с одного их дочерних узлов того узла, где вы зарегистрировали обработчик.

Для обхода проблемы можно использовать свойство relatedTarget объекта событий. Он сообщает, на каком узле была до этого мышь при возникновении события «mouseover», и на какой элемент она переходит при событии «mouseout». Нам надо менять эффект, только когда relatedTarget находится вне нашего целевого узла. Только в этом случае событие на самом деле представляет собой переход на наш узел (или уход с узла).

Функция isInside перебирает всех предков узла, пока не доходит до верха документа (и тогда узел равен null), или же не находит заданного ей родителя.

Должен добавить, что такой эффект достижим гораздо проще через псевдоселектор CSS под названием :hover, как показано ниже. Но когда при наведении вам надо делать что-то более сложное, чем изменение стиля узла, придётся использовать трюк с событиями «mouseover» и «mouseout».

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

Когда элемент прокручивается, запускается событие «scroll». Это используется во многих случаях, например чтобы узнать, на что сейчас пользователь смотрит (чтобы останавливать анимацию, не попавшую на экран, или отправлять секретные шпионские донесения в ваш злодейский штаб), или визуально демонстрировать прогресс (подсвечивая часть содержания или показывая номер страницы).

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

Позиция элемента fixed означает почти то же, что absolute, но ещё и предотвращает прокручивание элемента вместе с остальным документом. Смысл в том, чтобы оставить наш индикатор в углу. Внутри него находится другой элемент, который изменяет размер, отражая текущий прогресс. Мы используем проценты вместо px для задания ширины, чтобы размер элемента изменялся относительно размера всего индикатора.

Глобальная переменная innerHeight даёт высоту окна, которую надо вычесть из полной высоты прокручиваемого элемента – при достижении конца элемента прокрутка заканчивается. (Также в дополнение к innerHeight есть переменная innerWidth). Поделив текущую позицию прокрутки pageYOffset на максимальную позицию прокрутки, и умножив на 100, мы получили процент для индикатора.

Вызов preventDefault не предотвращает прокрутку. Обработчик события вызывается уже после того, как прокрутка случилась.

События, связанные с фокусом

При получении элементом фокуса браузер запускает событие “focus”. Когда он теряет фокус, запускается событие “blur”.

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

Следующий пример демонстрирует текст подсказки для того текстового поля, у которого в данный момент фокус.

Объект window получает события focus и blur, когда пользователь выделяет или убирает фокус с закладки браузера или окна браузера, в котором показан документ.

Событие загрузки

Когда заканчивается загрузка страницы, на объектах window и body запускается событие “load”. Это часто используется для планирования инициализирующих действий, которым необходим полностью построенный документ. Вспомните, что содержимое тегов

Представьте, что возведение в квадрат – очень тяжёлое, долго работающее вычисление, которое нам надо запустить фоновым потоком. Такой код порождает «рабочего», отправляет ему несколько сообщений, и выводит результаты.

Функция postMessage отправляет сообщение, которое запускает событие “message” у принимающей стороны. Скрипт, создавший рабочего, отправляет и получает сообщения через объект Worker, тогда как рабочий общается со скриптом, создавшим его, отправляя и получая сообщения через его собственное глобальное окружение – которое является отдельным окружением, не связанным с оригинальным скриптом.

Установка таймеров

Функция setTimeout схожа с requestAnimationFrame. Она планирует запуск другой функции в будущем. Но вместо вызова функции при следующей перерисовке страницы, она ждёт заданное в миллисекундах время. Эта страница через две секунды превращается из синей в жёлтую:

Иногда вам надо отменить запланированную функцию. Это можно сделать, сохранив значение, возвращаемое setTimeout, и затем вызвав с ним clearTimeout.

Функция cancelAnimationFrame работает так же, как clearTimeout – вызов её со значением, возвращённым requestAnimationFrame, отменит этот кадр (если он уже не был вызван).

Похожий набор функций, setInterval и clearInterval используется для установки таймеров, которые будут повторяться каждые X миллисекунд.

Устранение помех (debouncing)

У некоторых событий есть возможность выполняться быстро и много раз подряд (например, «mousemove» и «scroll»). При обработке таких событий надо быть осторожным и не делать ничего «тяжёлого», или ваш обработчик займёт столько времени на выполнение, что взаимодействие с документом будет медленным и прерывистым.

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

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

Если задать undefined для clearTimeout, или вызвать его с таймаутом, который уже произошёл, то ничего не произойдёт. Таким образом, не надо осторожничать при его вызове, и мы просто поступаем так для каждого события.

Можно использовать немного другой подход, если нам надо разделить ответы минимальными промежутками времени, но при этом запускать их в то время, когда происходят события, а не после. К примеру, надо реагировать на события «mousemove», показывая текущие координаты мыши, но только каждые 250 миллисекунд.

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

У событий есть определяющий их тип («keydown», «focus», и так далее). Большинство событий вызываются конкретными узлами DOM, и затем распространяются на их предков, позволяя связанными с ними обработчикам обрабатывать их.

При вызове обработчика ему передаётся объект события с дополнительной информацией о событии. У объекта также есть методы, позволяющие остановить дальнейшее распространение (stopPropagation) и предотвратить обработку события браузером по умолчанию (preventDefault).

Нажатия на клавиши запускают события «keydown», «keypress» и «keyup». Нажатия на кнопки мыши запускают события «mousedown», «mouseup» и «click». Движения мыши запускают события «mousemove», и возможно «mouseenter» и «mouseout».

Прокрутку можно обнаружить через событие “scroll”, а изменения фокуса через события «focus» и «blur». Когда заканчивается загрузка документа, у объекта window запускается событие “load”.

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

Упражнения

Цензура клавиатуры

В промежутке с 1928 по 2013 год турецкие законы запрещали использование букв Q, W и X в официальных документах. Это являлось частью общей инициативы подавления курдской культуры – эти буквы используются в языке курдов, но не у турков.

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

След мыши

В ранние дни JavaScript, когда было время кричащих домашних страниц с обилием анимированных картинок, люди использовали язык очень вдохновляющими способами. Одним из них был «след мыши» — серия картинок, которые следовали за курсором при его движении по странице.

Я хочу, что бы вы в упражнении сделали такой след. Используйте с абсолютным позиционированием, фиксированным размером и цветом фона. Создайте кучку элементов и при движении мыши показывайте их следом за курсором.

К этому можно подойти многими способами. Можно сделать очень простое или очень сложное решение, как угодно. Простое – хранить фиксированное количество элементов и проходить по ним в цикле, двигая каждый следующий на текущее место курсора, каждый раз когда случается событие «mousemove».

Закладки

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

В упражнении вам нужно сделать простой интерфейс закладок. Напишите функцию asTabs, которая принимает узел DOM, и создаёт закладочный интерфейс, показывая дочерние элементы этого узла. Ей нужно вставлять список элементов

Jquery, javascript. Событие по нажатии двух клавиш клавиатуры

Представьте, что вы разрабатываете движок для сайта с админкой. На сайте нет понятия «регистрация» и зарегистрированные пользователи. Царь и бог на нем только один — бородатый и бухой админ. Как бы вы сделали авторизацию для администратора сайта. Предусмотрели бы линк по типу http://адрес_сайта/admin ? Меня этот вариант не устроил. Я решил сделать невидимый блок с формой авторизация, который становится видимым при нажатии сочетания двух клавиш на клавиатуре. Передомной встала задача написать обработчик на Jquery и javascript. В статье опишу реализацию обработчика событий на javascript и jquery.

Принимая в расчет популярность библиотеки jquery — начнем реализуацию ее методами. По моей задумке функция переключения тригера «показать/скрыть форму». Стоит избегать таких сочетаний клавиш как ctrl+c/v/x. В своем примере я обрабатываю нажатие клавиш ctrl+q. Нам потребуется узнать коды клавиш. Позже я выложу таблицу с кодами клавиш. Итак, вот код реализации моей задумки:

Используя методы keydown() и keyup() мы отслеживаем нужные нам события, проверяем коды клавиш и запускаем определенные функцие: либо show(), либо hide() Так же я устанавливаю переменные куки. Делаю это для того, чтобы запоминать текущее положение тригера и подставлять его при переходе на другую страницу сайта.

Реализовать подобное на javascript можно следующим образом:

Я рекомендую использовать вариант с jquery в виду кроссбаузерности этой библиотеки.

Изучаем Java

Вы здесь: Главная >> Jquery-учебник >> Обработка событий в jQuery

Обучающие курсы:

Обработка событий в jQuery

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

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

В самом начале книги мы уже рассматривали возможность выполнения скриптов сразу после формирования структуры документа, не дожидаясь загрузки других элементов. Как вы уже знаете, обработать это событие можно с помощью метода ready () .

Если необходимо выполнить какие-либо действия только после полной загрузки самого HTML-документа, а также всех других элементов (например, изображений), то можно воспользоваться методом load (). Синтаксис метода таков.

Выведем подтверждающее сообщение и тип события после полной загрузки веб-страницы.

В результате выполнения получим два сообщения.

Документ полностью загружен
Тип события load

Для выполнения каких-либо действий непосредственно перед выгрузкой документа предназначен метод unload (). Метод имеет следующий синтаксис.
unload(Функция обратного вызова)

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

В этом разделе рассмотрим еще два полезных метода.

resize (Функция обратного вызова) — выполняется при изменении размера окна.

scroll (Функция обратного вызова) — выполняется при прокручивании содержимого элемента страницы, документа, окна или фрейма.

В параметре Функция обратного вызова указывается ссылка на функцию следующего формата.
function Название функции([Объект event]) <
// .
>

Обработать прокрутку содержимого окна и вывести сообщение можно так.
$(window).scroll(function() <
alert(«Прокрутка содержимого окна»);
>);

В качестве примера использования метода resize () получим ширину и высоту окна после изменения его размера (листинг 6.1).

Листинг 6.1. Вывод ширины и высоты окна при изменении размера

#4 — События. Часть 1.

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

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

На какие группы делятся события jQuery

В jQuery все события подразделяются на несколько групп. К ним относятся события браузера,
события клавиатуры, события мыши, события документа и т.д. Когда событие срабатывает, создается
новый объект events. Он содержит необходимую информацию о событии.

На этом занятии вы узнаете, как правильно записать методами jQuery события мыши (click)
и браузера (resize и scroll).

Приятного всем просмотра! Учитесь с удовольствием!

Вызов $(element).eventName(handler) привязывает обработчик handler к событию eventName элемента element, если обработчик события не указан ($(element).eventName()), то такой вызов приводит к срабатыванию события.

Топ-пост этого месяца:  Вывод постов из двух таксономий одновременно
Добавить комментарий