Создайте поле, которое будет предупреждать пользователя, если включен CapsLock. Выключение CapsLock уберёт предупреждение.
Такое поле может помочь избежать ошибок при вводе пароля.
Исходный документ: tutorial/browser/events/capslock-src/index.html.
JavaScript не имеет доступа к CapsLock. При загрузке страницы не известно, включён он или нет.
Но мы можем догадаться о его состоянии из событий:
- Проверив символ, полученный по
keypress. Символ в верхнем регистре без нажатого Shift означает, что включён CapsLock. Аналогично, символ в нижнем регистре, но с Shift говорят о включенном CapsLock. Свойствоevent.shiftKeyпоказывает, нажат ли Shift. Так мы можем точно узнать, нажат ли Caps Lock. - Проверять
keydown. Если нажат CapsLock (скан-код равен20), то переключить состояние, но лишь в том случае, когда оно уже известно.
Под Mac так делать не получится, посокльку клавиатурные события с CapsLock работают некорректно.
Имея состояние CapsLock в переменой, можно при фокусировке на INPUT выдавать предупреждение.
Отслеживать оба события: keydown и keypress хорошо бы на уровне документа, чтобы уже на момент входа в поле ввода мы знали состояние CapsLock.
Но при вводе сразу в нужный input событие keypress событие доплывёт до document и поставит состояние CapsLock после того, как сработает на input. Как это обойти — подумайте сами.
При загрузке страницы, когда еще ничего не набрано, мы ничего не знаем о состоянии CapsLock, поэтому оно равно null:
var capsLockEnabled = null;
Когда нажата клавиша, мы можем попытаться проверить, совпадает ли регистр символа и Shift:
document.onkeypress = function(e) {
e = e || event;
var chr = getChar(e);
if (!chr) return; // специальная клавиша
if (chr.toLowerCase() == chr.toUpperCase()) {
// символ, который не имеет регистра, такой как пробел,
// мы не можем использовать для определения состояния CapsLock
return;
}
capsLockEnabled = (chr.toLowerCase() == chr && e.shiftKey) || (chr.toUpperCase() == chr && !e.shiftKey);
}
Когда пользователь нажимает CapsLock, мы должны изменить его текущее состояние. Но мы можем сделать это только если знаем, что был нажат CapsLock.
Например, когда пользователь открыл страницу, мы не знаем, включен ли CapsLock. Затем, мы получаем событие keydown для CapsLock. Но мы все равно не знаем его состояния, был ли CapsLock выключен или, наоборот, включен.
if (nagivator.platform.substr(0,3) != 'Mac') { // событие для CapsLock глючит под Mac
document.onkeydown = function(e) {
e = e || event;
if (e.keyCode == 20 && capsLockEnabled !== null) {
capsLockEnabled = !capsLockEnabled;
}
}
}
Теперь поле. Задание состоит в том, чтобы предупредить пользователя о включенном CapsLock, чтобы уберечь его от неправильного ввода.
- Для начала, когда пользователь сфокусировался на поле, мы должны вывести предупреждение о CapsLock, если он включен.
- Пользователь начинает ввод. Каждое событие
keypressвсплывает до обработчикаdocument.keypress, который обновляет состояниеcapsLockEnabled.Мы не можем использовать событие
input.onkeypress, для отображения состояния пользователю, потому что оно сработает доdocument.onkeypress(из-за всплытия) и, следовательно, до того, как мы узнаем состояние CapsLock.Есть много способов решить эту проблему. Можно, например, назначить обработчик состояния CapsLock на событие
input.onkeyup. То есть, индикация будет с задержкой, но это несущественно.Альтернативное решение — добавить на
inputтакой же обработчик, как и наdocument.onkeypress. - ..И наконец, пользователь убирает фокус с поля. Предупреждение может быть видно, если CapsLock включен, но так как пользователь уже ушел с поля, то нам нужно спрятать предупреждение.
Код проверки поля:
<input type="text" onkeyup="checkCapsWarning(event)" onfocus="checkCapsWarning(event)" onblur="removeCapsWarning()"/>
<div style="display:none;color:red" id="caps">Внимание: нажат CapsLock!</div>
<script>
function checkCapsWarning() {
document.getElementById('caps').style.display = capsLockEnabled ? 'block' : 'none';
}
function removeCapsWarning() {
document.getElementById('caps').style.display = 'none';
}
</script>
Полный код решения: tutorial/browser/events/capslock/index.html.