Я лично предпочитаю многоключевой подход. Это позволяет обнаруживать несколько ключей, но также один и тот же ключ, и это работает в каждом браузере, который я тестировал.
map={}//declare object to hold data
onkeydown=onkeyup=function(e){
e=e||event//if e doesn't exist (like in IE), replace it with window.event
map[e.keyCode]=e.type=='keydown'?true:false
//Check for keycodes
}
Альтернативный метод - разделить события onkeydown
и onkeyup
и явно определить подэлементы карты в каждом событии:
map={}
onkeydown=function(e){
e=e||event
map[e.keyCode]=true
}
onkeyup=function(e){
e=e||event
map[e.keyCode]=false
}
В любом случае работает нормально. Теперь, чтобы фактически обнаружить нажатия клавиш, метод, включая исправления ошибок, таков:
//[in onkeydown or onkeyup function, after map[e.keyCode] has been decided...]
if(map[keycode]){
//do something
map={}
return false
}
map[keycode]
представляет собой определенный код клавиши, например 13
для Enter
или 17
для CTRL
.
Строка map={}
очищает объект карты, чтобы он не "держался" за клавиши в случае расфокусировки, в то время как return false
предотвращает, например, всплывающее окно "Закладки" при проверке на CTRL+D
. В некоторых случаях вы можете заменить его на e.preventDefault()
, но я обнаружил, что return false
более эффективен в большинстве случаев. Просто чтобы получить ясную перспективу, попробуйте это с CTRL+D
. Ctrl
равно 17
, а D
равно 68
. Обратите внимание, что без строки return false
появится диалоговое окно Закладки.
Вот несколько примеров:
if(map[17]&&map[13]){//CTRL+ENTER
alert('CTRL+ENTER was pressed')
map={}
return false
}else if(map[13]){//ENTER
alert('Enter was pressed')
map={}
return false
}
Следует иметь в виду, что меньшие комбинации должны быть последними. Всегда ставьте более крупные комбинации сначала в цепочке if..else, чтобы не получать оповещения одновременно для Enter
и CTRL+ENTER
.
Теперь полный пример, чтобы «собрать все вместе». Скажем, вы хотите предупредить сообщение, содержащее инструкции для входа, когда пользователь нажимает SHIFT+?
, и вход в систему, когда пользователь нажимает ENTER
. Этот пример также кросс-браузерно совместим, то есть он работает и в IE:
map={}
keydown=function(e){
e=e||event
map[e.keyCode]=true
if(map[16]&&map[191]){//SHIFT+?
alert('1) Type your username and password\n\n2) Hit Enter to log in')
map={}
return false
}else if(map[13]){//Enter
alert('Logging in...')
map={}
return false
}
}
keyup=function(e){
e=e||event
map[e.keyCode]=false
}
onkeydown=keydown
onkeyup=keyup//For Regular browsers
try{//for IE
document.attachEvent('onkeydown',keydown)
document.attachEvent('onkeyup',keyup)
}catch(e){
//do nothing
}
Обратите внимание, что некоторые специальные ключи имеют разные коды для разных двигателей. Но, как я уже проверял, это работает во всех браузерах, которые у меня есть на моем компьютере, включая Maxthon 3, Google Chrome, Internet Explorer (9 и 8) и Firefox.
Надеюсь, это было полезно.