Обработка событий в javascript
Содержание:
Использование функций javascript в атрибуте HTML onclick
Когда к щелчку нужно привязать выполнение нескольких действий javascript лучше использовать функции, а потом вызывать их в атрибуте onclick.
Например, напишем скрипт, который позволит по щелчку на кнопку скрыть один блок и показать другой.
XHTML
<p>
<input class=»button» type=»button» onclick=»showText()» value=»Нажми на меня!»/>
</p>
<div class=»hide-block1″>
Это блок, который нужно скрыть.
</div>
<div class=»show-block1″ style=”display:none;”>
Это блок, который нужно показать.
</div>
<script>
function showText() {
$(«.hide-block1»).fadeOut();
$(«.show-block1»).fadeIn();
}
</script>
|
1 |
<p> <input class=»button»type=»button»onclick=»showText()»value=»Нажми на меня!»/> </p> <div class=»hide-block1″> Это блок, который нужно скрыть. </div> <div class=»show-block1″style=”displaynone;”> Это блок, который нужно показать. </div> functionshowText(){ $(«.hide-block1»).fadeOut(); $(«.show-block1»).fadeIn(); } </script> |
Обратите внимание, что в самом атрибуте мы пишем только название функции. В данном случае showText(), а код самой функции мы пишем ниже и оборачиваем его в тег script
Применяем jQuery
Если в проекте используется библиотека jQuery, то можно ещё упростить код. Рассмотрим два самых распространенных способа:
$(function(){
$(".link").click(function() {
//действия
});
});
И ещё один вариант, который идентичен предыдущему.
$(function(){
$(".link").on("click", function(){
//действия
});
});
С обработчиком «on()» лучше ознакомиться отдельно, так как он несет в себе много полезного функционала. Например, возможность указать через пробел несколько событий к которым будет применяться действие, делегировать события на дочерние элементы, а так же он полезен если необходимо повесить событие на динамически добавляемые элементы, которых изначально нет на странице.
event.defaultPrevented
Свойство установлено в , если действие по умолчанию было предотвращено, и , если нет.
Рассмотрим практическое применение этого свойства для улучшения архитектуры.
Помните, в главе Всплытие и погружение мы говорили о и упоминали, что останавливать «всплытие» – плохо?
Иногда вместо этого мы можем использовать , чтобы просигналить другим обработчикам, что событие обработано.
Давайте посмотрим практический пример.
По умолчанию браузер при событии (клик правой кнопкой мыши) показывает контекстное меню со стандартными опциями. Мы можем отменить событие по умолчанию и показать своё меню, как здесь:
Теперь в дополнение к этому контекстному меню реализуем контекстное меню для всего документа.
При правом клике должно показываться ближайшее контекстное меню.
Проблема заключается в том, что когда мы кликаем по элементу , то мы получаем два меню: контекстное меню для кнопки и (событие всплывает вверх) контекстное меню для документа.
Как это поправить? Одно из решений – это подумать: «Когда мы обрабатываем правый клик в обработчике на кнопке, остановим всплытие», и вызвать :
Теперь контекстное меню для кнопки работает как задумано. Но цена слишком высока. Мы навсегда запретили доступ к информации о правых кликах для любого внешнего кода, включая счётчики, которые могли бы собирать статистику, и т.п. Это слегка неразумно.
Альтернативным решением было бы проверить в обработчике , было ли отменено действие по умолчанию? Если да, тогда событие было обработано, и нам не нужно на него реагировать.
Сейчас всё работает правильно. Если у нас есть вложенные элементы и каждый из них имеет контекстное меню, то код также будет работать. Просто убедитесь, что проверяете в каждом обработчике .
event.stopPropagation() и event.preventDefault()
Как мы можем видеть, и (также известный как ) – это две разные функции. Они никак не связаны друг с другом.
Архитектура вложенных контекстных меню
Есть также несколько альтернативных путей, чтобы реализовать вложенные контекстные меню. Одним из них является единый глобальный объект с обработчиком и методами, позволяющими хранить в нём другие обработчики.
Объект будет перехватывать любой клик правой кнопкой мыши, просматривать сохранённые обработчики и запускать соответствующий.
Но при этом каждый фрагмент кода, которому требуется контекстное меню, должен знать об этом объекте и использовать его вместо собственного обработчика .
Обработчик события как атрибут элемента
Это самый старый способ назначения обработчиков события и наименее используемый на данный момент. Для того чтобы его добавить, необходимо к имени события добавить приставку «on» и записать примерно такой код:
Обработчик события как атрибут
JavaScript
<button onclick=’alert(«Событие произошло!»)’>Нажми меня</button>
| 1 | <button onclick=’alert(«Событие произошло!»)’>Нажмименя<button> |
Нажми меня
Можно вызвать функцию, в которую можно передать один или несколько аргументов:
Обработчик события как атрибут элемента
JavaScript
<script>
function change(element, color){
element.style.backgroundColor = color;
}
</script>
<p onclick=»change(this, ‘red’)»>Кликни здесь, и этот абзац станет красным.
Но только один раз.</p>
<p onclick=»change(this, ‘lime’)»>Кликни здесь, и этот абзац станет зеленым.
Но только один раз.</p>
|
1 |
<script> functionchange(element,color){ element.style.backgroundColor=color; } <ponclick=»change(this, ‘red’)»>Кликниздесь,иэтотабзацстанеткрасным. Нотолькоодинраз.<p> <ponclick=»change(this, ‘lime’)»>Кликниздесь,иэтотабзацстанетзеленым. Нотолькоодинраз.<p> |
Пример этого кода:
Кликни здесь, и этот абзац станет красным. Но только один раз.
Кликни здесь, и этот абзац станет зеленым. Но только один раз.
Недостатком этого способа является то, что, если добавлять обработчики событий нужно к большому количеству элементов, то, во-первых, легко допустить ошибку в каком-нибудь из них, а во-вторых, при изменении кода сделать это придется долго. И опять-таки можно допустить ошибку.
Использовать этот способ нужно в учебных целях поначалу, а также тогда, когда это самый простой способ или нужно очень быстро добавить обработчик события к 1 элементу.
Достоинства и недостатки такого способа
Давайте теперь обсудим достоинства и недостатки
этого способа.
Достоинства
Достоинства такие: теперь,
если мы захотим задать одновременно одно событие всем
инпутам на странице, нет нужды вручную прописывать каждому
из них атрибут с событием. Можно просто получить все инпуты,
перебрать их циклом и каждому привязать событие.
Давайте сделаем это. Получим все инпуты с помощью getElementsByTagName
и в цикле привяжем каждому такое событие: пусть по клику каждый инпут
выдает алертом текст ‘!’:
Теперь нажатие на любой инпут будет приводить к тому,
что будет срабатывать функция func, которая алертом выводит ‘!’.
Использование this
Давайте усложним задачу и сделаем так,
чтобы alert выводил содержимое атрибута value того инпута,
на который кликнули мышкой.
Для этого нужно воспользоваться this, только не так, как мы это делали раньше.
Раньше, когда мы писали событие прямо в атрибут, мы делали так: onclick=»func(this)»,
однако сейчас вот так — elems.onclick = func(this) — мы сделать не можем.
Во-первых, потому, что функцию func здесь нужно писать без круглых скобок,
иначе будет не исходный код, а результат работы функции.
Во-вторых, this указывает на разные элементы в зависимости от контекста
(в зависимости от места, где он написан). И в нашем случае он не будет ссылаться
на нужный нам элемент (то есть на тот, на который мы кликнули).
Про контекст выполнения поговорим чуть позже, пока просто знайте, что он есть.
Вы можете спросить, почему тут — onclick=»func()» — в функции написаны круглые скобки, хотя по логике
там тоже требуется исходный код, а не результат.
Об этом вы узнаете в уроке про анонимные функции чуть позже.
Так как правильно использовать this в нашей конструкции elems.onclick = func?
На самом деле тут this доступен внутри функции func и он ссылается на тот элемент,
в котором возникло событие, вызвавшее эту функцию. То есть, если я делаю клик по первому
инпуту — в this будет лежать ссылка на него, а если по второму — то на него.
В данном случае считайте, что this — это будто переменная elem,
полученная через getElementById. К примеру, elem.value позволяет обратиться
к атрибуту value, значит this.value будет делать то же самое.
Итак, давайте все-таки решим нашу задачу — сделаем так,
чтобы alert выводил содержимое атрибута value того инпута,
на который кликнули мышкой:
Учтите, что если вы попытаетесь воспользоваться this
внутри функции, которая была прописана прямо в атрибуте (то есть первым способом задать событие) — у
вас ничего не выйдет. Смотрите пример неправильного кода:
В данном случае контекст выполнения таков, что this ссылается на
window, а не на текущий элемент. Почему так — поговорим, когда вы разберете анонимные функции.
Напоминаю правильный вариант:
Недостатки
Теперь поговорим о недостатках.
Недостатком такого способа будет то,
что мы можем привязать к событию только одну функцию.
Если попытаться сначала записать одну функцию, а потом другую —
у нас ничего не получится.
В следующем примере мы пытаемся привязать к событию onclick
сразу две функции func1 и func2. Однако по клику на элемент сработает
только вторая функция, так как она затрет первую:
В принципе, эту проблему легко обойти, если ввести еще и третью функцию func3.
Привяжем к атрибуту onclick только func3, а она пусть вызывает func1 и func2 у себя внутри:
Как вы видите, этот недостаток не слишком существенный и его легко обойти.
Только что вводится лишняя функция, что немного неудобно.
Однако, есть еще один недостаток — мы не можем легко отвязать от onclick, к примеру, только
функцию func1, оставив func2 привязанным. Можно, конечно же, накрутить большие конструкции
кода, однако это не нужно, если пользоваться еще более продвинутым способом
привязать событие — через addEventListener. Давайте посмотрим, как с работать
с этой функцией:
javascript onclick без клика
javascript onclick без клика
но первое, что я подумал… вспомнил старый пошлый анекдот! дети, если вам нет 16, то закрываем страницу на этом месте!
Закрыли!? Я жду!
Теперь продолжим со взрослыми…
Встречается парочка на хате, а у парня был попугай! Девушка:
— я не могу заниматься этим, когда он смотрит…
Парень накинул тряпку на клетку.
И говорит попугаю! Будешь подсматривать — голову оторву!
Начали заниматься любовью!
— Давай я сверху, ты снизу!
— Давай!
…
— Давай ты сверху, я снизу!
— Давай!
…
— А теперь давай ты сверху, и я сверху!
Попугай:
— Пусть мне оторвут голову! Но это я должен увидеть!
Частые ошибки
Если вы только начинаете работать с событиями, обратите внимание на следующие моменты. Функция должна быть присвоена как , а не
Функция должна быть присвоена как , а не .
Если добавить скобки, то – это уже вызов функции, результат которого (равный , так как функция ничего не возвращает) будет присвоен . Так что это не будет работать.
…А вот в разметке, в отличие от свойства, скобки нужны:
Это различие просто объяснить. При создании обработчика браузером из атрибута, он автоматически создаёт функцию с телом из значения атрибута: .
Так что разметка генерирует такое свойство:
Используйте именно функции, а не строки.
Назначение обработчика строкой также сработает. Это сделано из соображений совместимости, но делать так не рекомендуется.
Не используйте для обработчиков.
Такой вызов работать не будет:
Регистр DOM-свойства имеет значение.
Используйте , а не , потому что DOM-свойства чувствительны к регистру.
Типы событий мыши
Условно можно разделить события на два типа: «простые» и «комплексные».
- Кнопка мыши нажата над элементом.
- Кнопка мыши отпущена над элементом.
- Мышь появилась над элементом.
- Мышь ушла с элемента.
- Каждое движение мыши над элементом генерирует это событие.
- Вызывается при клике мышью, то есть при , а затем на одном элементе
- Вызывается при клике правой кнопкой мыши на элементе.
- Вызывается при двойном клике по элементу.
Комплексные можно составить из простых, поэтому в теории можно было бы обойтись вообще без них. Но они есть, и это хорошо, потому что с ними удобнее.
Одно действие может вызывать несколько событий.
Например, клик вызывает сначала при нажатии, а затем и при отпускании кнопки.
В тех случаях, когда одно действие генерирует несколько событий, их порядок фиксирован. То есть, обработчики вызовутся в порядке → → .
Кликните по кнопке ниже и вы увидите, какие при этом происходят события. Попробуйте также двойной клик.
На тест-стенде ниже все мышиные события записываются, и если между событиями проходит больше 1 секунды, то они для удобства чтения отделяются линией. Также присутствуют свойства , по которым можно определить кнопку мыши. Мы их рассмотрим далее.
Каждое событие обрабатывается независимо.
Например, при клике события возникают одновременно, но обрабатываются последовательно. Сначала полностью завершается обработка , затем запускается .
Движение мыши
Каждый раз, когда перемещается курсов мыши, срабатывает событие «mousemove» из набора JavaScript mouse events. Оно может быть использовано для отслеживания положения мыши. Это применяется при реализации возможности перетаскивания элементов мышью.
В следующем примере программа выводит на экран панель и устанавливает обработчики событий таким образом, что при перетаскивании эта панель становится уже или шире:
<p>Потяните за край панели, чтобы изменить ее ширину:</p>
<div style="background: orange; width: 60px; height: 20px">
</div>
<script>
var lastX; // Отслеживает последнюю позицию X мыши
var rect = document.querySelector("div");
rect.addEventListener("mousedown", function(event) {
if (event.which == 1) {
lastX = event.pageX;
addEventListener("mousemove", moved);
event.preventDefault(); // Предотвращает выделение
}
});
function buttonPressed(event) {
if (event.buttons == null)
return event.which != 0;
else
return event.buttons != 0;
}
function moved(event) {
if (!buttonPressed(event)) {
removeEventListener("mousemove", moved);
} else {
var dist = event.pageX - lastX;
var newWidth = Math.max(10, rect.offsetWidth + dist);
rect.style.width = newWidth + "px";
lastX = event.pageX;
}
}
</script>
Обратите внимание, что обработчик «mousemove» зарегистрирован для всего окна. Даже если во время изменения размеров мышь выходит за пределы панели, мы все равно обновляем ширину панели и прекращаем JavaScript touch events, когда клавиша мыши была отпущена
Мы должны прекратить изменение размера панели, когда пользователь отпускает клавишу мыши. К сожалению, не все браузеры устанавливают для событий «mousemove» свойство which. Существует стандартное свойство buttons, которое предоставляет аналогичную информацию, но оно также поддерживается не во всех браузерах. К счастью, все основные браузеры поддерживают что-то одно: либо buttons, либо which. Функция buttonPressed в приведенном выше примере сначала пытается использовать свойство buttons, и, если оно не доступно, переходит к which.
Когда курсор мыши наводится или покидает узел, запускаются события «mouseover» или «mouseout«. Они могут использоваться для создания эффектов при наведении курсора мыши, вывода какой-нибудь подписи или изменения стиля элемента.
Чтобы создать такой эффект, недостаточно просто начать его отображение при возникновении события «mouseover» и завершить после события «mouseout«. Когда мышь перемещается от узла к одному из его дочерних элементов, для родительского узла происходит событие «mouseout«. Хотя указатель мыши не покинул диапазон распространения узла.
Что еще хуже, эти JavaScript event распространяются так же, как и другие события. Когда мышь покидает один из дочерних узлов, для которого зарегистрирован обработчик, возникнет событие «mouseout«.
Чтобы обойти эту проблему, можно использовать свойство объекта события relatedTarget. В случае возникновения события «mouseover» оно указывает, на какой элемент был наведен курсор мыши до этого. А в случае возникновения «mouseout» — к какому элементу перемещается указатель. Мы будем изменять эффект наведения мыши только, когда relatedTarget находится вне нашего целевого узла.
В этом случае мы изменяем поведение, потому что курсор мыши был наведен на узел из-за его пределов (или наоборот):
<p>Наведите курсор мыши на этот <strong>абзац</strong>.</p>
<script>
var para = document.querySelector("p");
function isInside(node, target) {
for (; node != null; node = node.parentNode)
if (node == target) return true;
}
para.addEventListener("mouseover", function(event) {
if (!isInside(event.relatedTarget, para))
para.style.color = "red";
});
para.addEventListener("mouseout", function(event) {
if (!isInside(event.relatedTarget, para))
para.style.color = "";
});
</script>
Функция isInside отслеживает родительские связи заданного узла или пока не будет достигнута верхняя часть документа (когда node равен нулю). Либо не будет найден родительский элемент, который нам нужен.
Эффект наведения гораздо проще создать с помощью псевдоселектора CSS :hover, как показано в следующем примере. Но когда эффект наведения предполагает что-то более сложное, чем просто изменение стиля целевого узла, тогда нужно использовать прием с использованием событий «mouseover» и «mouseout» (JavaScript mouse events):
<style>
p:hover { color: red }
</style>
<p>Наведите курсор мыши на этот <strong>абзац</strong>.</p>
setTimeout()
Как мы ранее отметили, setTimeout () выполняет определённый блок кода один раз по истечении заданного времени. Принимает следующие параметры:
- Функция для запуска или ссылка на функцию, определённую в другом месте.
- Число, представляющее интервал времени в миллисекундах (1000 миллисекунд равняется 1 секунде) ожидания перед выполнением кода. Если вы укажете значение 0 (или просто опустите значение), функция запустится как можно скорее. (См. Примечание ниже о том, почему он запускается «как можно скорее», а не «сразу».) Подробнее о том, почему вы, возможно, захотите сделать это позже.
- Значений, представляющие любые параметры, которые вы хотите передать функции при её запуске.
NOTE: Указанное время (или задержка) не является гарантированным временем выполнения, а скорее минимальным временем выполнения. Обратные вызовы, которые вы передаёте этим функциям, не могут выполняться, пока стек в основном потоке не станет пустым.
Как следствие, такой код, как setTimeout (fn, 0), будет выполняться, как только стек будет пуст, а не сразу. Если вы выполните такой код, как setTimeout (fn, 0), но сразу после выполнения цикла, который насчитывает от 1 до 10 миллиардов, ваш колбэк будет выполнен через несколько секунд.
В следующем примере, браузер будет ожидать две секунды перед тем как выполнит анонимную функцию, тогда отобразит сообщение (живой пример, и исходный код):
Указанные вами функции не обязательно должны быть анонимными. Вы можете дать своей функции имя и даже определить её где-нибудь ещё и передать ссылку на функцию в setTimeout (). Следующие две версии фрагмента кода эквивалентны первой:
Это может быть полезно, если у вас есть функция, которую нужно вызывать как по таймауту, так например и в ответ на событие. Но это также может помочь поддерживать ваш код в чистоте, особенно если колбэк тайм-аута занимает больше, чем несколько строк кода.
возвращает значение идентификатора, которое можно использовать для ссылки на тайм-аут позже, например, когда вы хотите его остановить.
Любые параметры, которые вы хотите передать функции, выполняемой внутри setTimeout (), должны быть переданы ей как дополнительные параметры в конце списка.
Например, вы можете реорганизовать предыдущую функцию, чтобы она передавала привет любому имени, переданному ей:
Теперь вы можете передать имя в вызов setTimeout () в качестве третьего параметра:
Наконец, если был создан тайм-аут, вы можете отменить его до истечения указанного времени, вызвав , передав ему идентификатор вызова в качестве параметра. Итак, чтобы отменить указанный выше тайм-аут, вы должны сделать следующее:
Note: См. для более полной демонстрации, которая позволяет вам указать имя для приветствия и отменить приветствие с помощью отдельной кнопки (см. исходный код).
Решение в лоб
<li>
<a href="#" onclick="aclick('div25');return false;">Заголовок пункта<a>
<div id="div25">Текст пункта<div>
<li>
|
Каждому блоку вешаем уникальный ID. В ссылке прописываем обработчик, который вызывает функцию (в нашем случае aclick), передавая ей ID связанного с этой ссылкой блока. Обработчик же занимается раскрыванием/скрыванием полученного в аргументе блока.
Минусы данного решения
Первый минус — много мусора в HTML.
Второй минус более существенен. Здесь мы используем процедурное программирование со всеми его недостатками.
В чём главный недостаток процедурного программирования? В том, что данные не связаны с обрабатывающим их кодом. Вот и у нас здесь куча ссылок, куча блоков и одна функция которая их всех разруливает.
Каждому немного знающему JS очевидно, что блок нельзя раскрыть простым циклом с задержками, типа следующего:
function aclick(divid) {
var div = document.getElementById(divid);
div.style.height = "0";
for (var i = 10; i < 500; i += 10) {
usleep(100);
div.style.height = i + "px";
}
}
|
При таком цикле браузер просто полностью повиснет на несколько секунд. Причём в большинстве браузеров блок отрисуется только целиком в конце.
Поэтому, хотя нам этого явно не хотелось, придётся использовать таймеры и потихоньку открывать блок.
И вот у нас получается несколько параллельно идущих процессов со связанными с ними данными (таймер, состояние и т.п). И все их разруливает одна единственная функция. Несчастная функция.
Наиболее частое решение — использовать массивы значений.
var divs = {};
var timers = {};
function aclick(divid) {
divsdivid = document.getElementById(divid);
...
timersdivid = setInterval(...);
...
}
|
Массивы хранятся в глобальных переменных. Их нужно вовремя инициализовывать, сбрасывать и т.д. и т.п.
Вобщем, вместо удовольствия от любимой работы, получаем в крайнем случае удовольствие анальное.
Ещё вариант хранить данные привязанные к блоку в свойствах DOM-объекта этого блока. Уже лучше, но заморочек по прежнему хватает.
Распространение
Обработчики событий (например, JavaScript touch events), зарегистрированные для родительских узлов, также будут принимать события, которые происходят в дочерних элементах. Если была нажата кнопка, находящаяся внутри абзаца, обработчики событий абзаца также получат событие click.
Событие распространяется от узла, в котором оно произошло, в родительский узел и в корень документа. После того, как все обработчики, зарегистрированные в конкретном узле, вступили в действие по очереди, возможность реагировать на событие получают обработчики, зарегистрированные для всего окна.
В любой момент обработчик события может вызвать для объекта события метод stopPropagation, чтобы предотвратить распространение события дальше. Это может быть полезно, когда у вас есть кнопка внутри другого интерактивного элемента, и вы не хотите, чтобы при нажатии кнопки активировалось поведение, заданное для клика мышью по внешним элементам.
В следующем примере мы регистрируем обработчики «MouseDown» как для кнопки, так и для абзаца. При клике правой клавишей (JavaScript mouse events) обработчик вызывает метод stopPropagation, который предотвращает запуск обработчика абзаца. При нажатии на кнопку другой клавишей мыши запускаются оба обработчика:
<p>Абзац и в нем <button>кнопка</button>.</p>
<script>
var para = document.querySelector("p");
var button = document.querySelector("button");
para.addEventListener("mousedown", function() {
console.log("Handler for paragraph.");
});
button.addEventListener("mousedown", function(event) {
console.log("Handler for button.");
if (event.which == 3)
event.stopPropagation();
});
</script>
Большинство объектов событий имеют свойство target, которое указывает на узел, в котором они возникли. Вы можете использовать это свойство, чтобы случайно не обрабатывать какое-то событие, которое распространяется вверх из узла.
Также можно использовать JavaScript event target, чтобы расширить диапазон события определенного типа. Например, если у вас есть узел, содержащий длинный список кнопок, более удобно зарегистрировать один обработчик клика для внешнего узла и использовать свойство target, чтобы отслеживать, была ли нажата кнопка, а не регистрировать экземпляры обработчика для всех кнопок:
<button>A</button>
<button>B</button>
<button>C</button>
<script>
document.body.addEventListener("click", function(event) {
if (event.target.nodeName == "BUTTON")
console.log("Clicked", event.target.textContent);
});
</script>
События клавиш
Когда пользователь нажимает клавишу на клавиатуре, браузер запускает событие «keydown«. Когда он отпускает клавишу, срабатывает событие «keyup«:
<p>Эта страница становится фиолетовой, когда вы нажимаете клавишу V.</p>
<script>
addEventListener("keydown", function(event) {
if (event.keyCode == 86)
document.body.style.background = "violet";
});
addEventListener("keyup", function(event) {
if (event.keyCode == 86)
document.body.style.background = "";
});
</script>
Также это событие срабатывает, когда пользователь нажимает и удерживает клавишу, или пока клавиша удерживается. Например, если требуется увеличить скорость персонажа в игре, нажав на клавишу со стрелкой, и снова уменьшить ее, отпустив клавишу, то нужно быть осторожным, чтобы не увеличивать скорость каждый раз, пока клавиша нажата.
В предыдущем примере использовано свойство объекта event keycode JavaScript. С его помощью определяется, какая именно клавиша была нажата или отпущена. Ноне всегда очевидно, как привести числовой код клавиши к фактической клавише.
Для считывания значений клавиш букв и цифр используется код символа Unicode. Он связан с буквой (в верхнем регистре) или цифрой, обозначенной на клавише. Метод charCodeAt для строк позволяет получить это значение:
console.log("Violet".charCodeAt(0));
// → 86
console.log("1".charCodeAt(0));
// → 49
С другими клавишами связаны менее предсказуемые коды клавиш. Лучший способ определить нужный код, это поэкспериментировать. Зарегистрировать обработчик события нажатия клавиши, который фиксирует коды клавиш, которые он получает, и нажать нужную клавишу.
Такие клавиши, как Shift, Ctrl, Alt порождают события, как обычные клавиши. Но при отслеживании комбинаций клавиш также можно определить, нажаты ли эти клавиши, по свойствам событий клавиатуры и JavaScript mouse events: shiftKey, ctrlKey, altKey и metaKey:
<p>Чтобы продолжить, нажмите Ctrl-Space.</p>
<script>
addEventListener("keydown", function(event) {
if (event.keyCode == 32 && event.ctrlKey)
console.log("Continuing!");
});
</script>
События «keydown» и «keyup» предоставляют информацию о фактическом нажатии клавиш. Но что, если нам нужен сам вводимый текст? Получать текст из кодов клавиш неудобно. Для этого существует событие, «keypress«, которое срабатывает сразу после «keydown«. Оно повторяется вместе с «keydown«, пока клавиша нажата. Но только для клавиш, с помощью которых производится ввод символов.
Свойство charCode в объекте события содержит код, который может быть интерпретирован, как код символа Unicode. Мы можем использовать функцию String.fromCharCode, чтобы преобразовать этот код в строку из одного символа.
<p>Установите фокус ввода на этой странице и наберите что-нибудь.</p>
<script>
addEventListener("keypress", function(event) {
console.log(String.fromCharCode(event.charCode));
});
</script>
Узел DOM, в котором происходит событие зависит, от того элемента, который находился в фокусе ввода при нажатии клавиши. Обычные узлы не могут находиться в фокусе ввода (если не установить для них атрибут tabindex), но такие элементы, как ссылки, кнопки и поля формы, могут.
Если никакой конкретный элемент не выделен фокусом ввода, то в качестве целевого узла для событий клавиши и JavaScript touch events выступает document.body.