Мастер-классы по Javascript Екатеринбург Ростов-на-Дону Москва Узнать больше...
Содержание (скрыть) Содержание (показать)

Поле, предупреждающее о включенном CapsLock

Создайте поле, которое будет предупреждать пользователя, если включен CapsLock. Выключение CapsLock уберёт предупреждение.

Такое поле может помочь избежать ошибок при вводе пароля.

Исходный документ: tutorial/browser/events/capslock-src/index.html.

Алгоритм
Решение
Алгоритм

JavaScript не имеет доступа к CapsLock. При загрузке страницы не известно, включён он или нет.

Но мы можем догадаться о его состоянии из событий:

  1. Проверив символ, полученный по keypress. Символ в верхнем регистре без нажатого Shift означает, что включён CapsLock. Аналогично, символ в нижнем регистре, но с Shift говорят о включенном CapsLock. Свойство event.shiftKey показывает, нажат ли Shift. Так мы можем точно узнать, нажат ли Caps Lock.
  2. Проверять 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, чтобы уберечь его от неправильного ввода.

  1. Для начала, когда пользователь сфокусировался на поле, мы должны вывести предупреждение о CapsLock, если он включен.
  2. Пользователь начинает ввод. Каждое событие keypress всплывает до обработчика document.keypress, который обновляет состояние capsLockEnabled.

    Мы не можем использовать событие input.onkeypress, для отображения состояния пользователю, потому что оно сработает до document.onkeypress (из-за всплытия) и, следовательно, до того, как мы узнаем состояние CapsLock.

    Есть много способов решить эту проблему. Можно, например, назначить обработчик состояния CapsLock на событие input.onkeyup. То есть, индикация будет с задержкой, но это несущественно.

    Альтернативное решение — добавить на input такой же обработчик, как и на document.onkeypress.

  3. ..И наконец, пользователь убирает фокус с поля. Предупреждение может быть видно, если 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.

#129
Наверх

Реклама

Нашли опечатку?

Нашли опечатку на сайте? Что-то кажется странным?
Выделите соответствующий текст и нажмите Ctrl+Enter!

Последние Комментарии

Помоги другим!

Помоги другим узнать о хорошей статье!