JavaScript

индекс
246,46

Не кроссбраузерный event

Здравстуйте, уважаемое хабрасообщество. Реквестирую консультацию.
Позавчера, во время разработки jQuery.keyboard столкнулся с абсолютной браузерной несовместимостью, ужасно неприятной непоследовательностью и т.д. в возврашении значения event.keyCode в различных браузерах. На удивление, единственный, кто меня порадовал — IE 6 (ies4linux) и больше всех огорчила — опера 10. Хромиум и фокс же ж вернули приблизительно одинаковый результат.


Итак, сперва — код теста:

<!DOCTYPE html>
<
html>
    <
head>
        <
meta http-equiv='content-type' content='text/html; charset=utf-8' />
        <
title>Javascript Event Test</title>
    </
head>
    <
body></body>
    <
script type='text/javascript'>
var keys = {};
var 
body document.getElementsByTagName("body")[0];

var 
dumpObj = function (obj) {
    var 
dump "";
    for (var 
i in obj) {
        
dump += ":" obj[i] + "; ";
    }
    return 
dump;
}

document.onkeydown = function (e) {
    
|| event;
    
keys[e.keyCode] = 1;
    
body.innerHTML += dumpObj(keys) + "<br />";
}

document.onkeyup = function (e) {
    
|| event;
    
keys[e.keyCode] = 0;
}
    </script>
</html>


и теперь — результаты (пишу клавишесочетание и вернувшиеся коды):

Во всех браузерах

shift — 16
ctrl  — 17
alt   — 18

IE и то, как я ожидал (порядок неважен)

shift + ctrl — 16+17
shift + alt  — 16+18
ctrl  + alt  — 17+18

Firefox 3.5

shift + ctrl  — 16+0
ctrl  + shift — 17+0
shift + alt   — 16+224
alt   + shift — 18+16
ctrl  + alt   — 17+18
alt   + ctrl  — 18+17

Chromium 4

shift + ctrl  — 16+0
ctrl  + shift — 17+0
shift + alt   — 16+91
alt   + shift — 18+16
ctrl  + alt   — 17+18
alt   + ctrl  — 18+17

Opera 10

shift + ctrl  — 16 (при нажатии на Ctrl событие не срабатывает)
ctrl  + shift — 17 (при нажатии на Shift событие не срабатывает)
shift + alt   — 16+0
alt   + shift — 18 (при нажатии на Shift событие не срабатывает)
ctrl  + alt   — 17+18
alt   + ctrl  — 18 (при нажатии на Ctrl событие не срабатывает)


Подозреваю, что в Маке с кнопкой Meta дела обстоят подобным образом.
Теперь — вопросы:
1. Зачем этот беспредел был устроен в «правильных» браузерах? Никакой последовательности. Даже Гекко и ВебКит, выдающие приблизительно одинаковые результаты — не смогли определится с кодом shift+alt
2. Что за пиз странный подход у Оперы? Допустим, проблемы Фокса и Хрома можно решить, отслеживая свойства event.shiftKey и подобные, или занеся таблицу соответствий. Например, что 224 на самом деле не что иное, как 18
3. Самое простое решение — это было бы поступить так, как в плагине «Handling Keyboard Shortcuts». Данный подход мгновенно решил бы множество проблем, но в нём можно делать комбинации только с помощью Ctrl/Alt/Shift + одна клавиша. Комбинации ал-ля Space+X или C+V+B там не пройдут, что меня совсем не радует.
4. Где бы узнать какие еще есть несоответствия у этих браузеров. Как, кстати, поступают ИЕ7 и ИЕ8, ато я сижу на Линуксе и проверить не могу.
5. Кто-то может что-то добавить от себя?

Плюс еще один ньюанс. В прошлом топике anatoly-rr заметил интересный баг моей библиотеки. Суть бага в том, что когда зажимается клавиша на объекте происходит событие keydown, если же снять фокус с объекта и отжать клавишу — события keyup не происходит, потому клавиша всё еще считается зажатой. На данный момент я думаю решить это так — повесить, чтобы при onblur стирались все зажатые клавиши, но может есть более изящное решение?

По мере возникновения вопросов (и появления решений) по евенту я думаю дополнять этот топик и сообщать об этом в комментах

Не кроссплатформенно?


Тут мне сообщаются, что в Windows подобных проблем ни в одном браузере нет? Неужели это проблема только в браузерах под Линукс, продолжение истории с русской раскладкой в фоксе? Если так, то, пожалуй, придётся писать три баг-репорта. Но идея, что моё приложение не будет поддерживаться браузерами под Линуксом меня совсем не радует, потому ­— всё еще принимаю предложения.
+19
28 ноября 2009, 01:30
23

комментарии (46)

+6
khizhaster #
Вот, вы не первые: unixpapa.com/js/key.html ;-)
Вобщем, если вам нужны модификаторы, то есть event.altKey, event.ctrlKey, event.shiftKey, event.metaKey. А если отдельно именно кнопки, то да, маленько геморроя есть.
–9
LeeMiller #
«Некроссбраузерный» читать как некро? правила_русского
+1
SMiX #
Винда на виртуалке:
Chromium 3(Stable)
16:1; 116:0;
16:1; 17:1; 116:0;
16:0; 17:1; 116:0;
16:1; 17:1; 116:0;
16:1; 17:0; 116:0;
16:1; 17:0; 18:1; 116:0;
16:0; 17:0; 18:1; 116:0;
16:1; 17:0; 18:1; 116:0;
16:0; 17:1; 18:0; 116:0;
16:0; 17:1; 18:1; 116:0;
16:0; 17:0; 18:1; 116:0;
16:0; 17:1; 18:1; 116:0;

IE
16:1;
16:1; 17:1;
16:0; 17:1;
16:1; 17:1;
16:1; 17:0;
16:1; 17:0; 18:1;
16:1; 17:0; 18:0;
16:0; 17:1; 18:0;
16:0; 17:1; 18:1;
16:0; 17:0; 18:1;
16:0; 17:1; 18:1;
16:0; 17:1; 18:0;
0
SMiX #
Порядок сочетаний взял из Ваших результатов по Хромиуму
0
demmsnt #
Что, то мне кажется это GTK так капризничает
+1
1602 #
net.tutsplus.com/articles/web-roundups/17-hours-of-javascript-from-the-masters/
9: Javascript Events

В этом скринкасте Peter-Paul Koch очень доходчиво говорит про события. Мне вчера очень помогло, может и вам поможет.
+1
1602 #
Игнорируйте слово скринкаст. Написал автоматом. Не скринкаст это конечно же )
0
arty #
ну и не стоит забывать о мегапопулярном ресурсе того же автора quirksmode.org, где он разбирает в том числе и несовместимости клавиатурных событий
+1
licvidator #
А event.which не спасает?
https://developer.mozilla.org/en/DOM/event.which
+1
TheShock #
нет, та же реакция…
+2
Zibx #
Там ещё есть ctrlKey, altKey и специально подумали о маках: metaKey.
+5
Goodkat #
К тому же Firefox по-разному реагирует на клавиатурные события в Linux и Windows

Welcome in webdev :)
+1
dkrnl #
может дело в xorg?
0
arty #
вы ещё на маке их не пробовали, там тоже повеселитесь; ))
НЛО прилетело и опубликовало эту надпись здесь
–3
homm #
Брысь под лавку. В Опере все отлично, проблема в линуксе.
НЛО прилетело и опубликовало эту надпись здесь
0
homm #
Виндовс:
Все браузеры ОК.
Линукс:
Все браузеры глючат.

Виноват Зевс, определенно.
НЛО прилетело и опубликовало эту надпись здесь
–2
homm #
Дятел, это и есть пост про подобный баг и в фаерфоксе тоже.
НЛО прилетело и опубликовало эту надпись здесь
–2
homm #
8 дней назад. Я удовлетворил ваше любопытство?
НЛО прилетело и опубликовало эту надпись здесь
+3
Gospodin #
Складывается такое впечатление что веб-разработка для вас начинается строкой alert('Hello World') и заканчивается alert('Bye world'), вы абсолютно неадекватно реагируете на баги Оперы, поверьте эти баги не столь критичны что с ними нельзя совладать. Из личного опыта могу сказать что с клавиатурными событиями все браузеры работают абсолютно по-разному, месяца 3 назад писал Input Mask, как там я это понял в полной мере, однако если сразу обратить на это внимание то код при этом удлинится максимум на 10 строчек (если не учитывать код по работе с кареткой в IE и не IE), при этом будут учтены все особенности работы основных браузеров Opera, IE, FF, Chrome/Safari. Так что не надо во всех смертных грехах обвинять оперу, вы просто этим пытаетесь оправдать собственную лень.
НЛО прилетело и опубликовало эту надпись здесь
+2
homm #
Поясню. Виноваты девелоперы оперы
Неожиданно, правда? :)
НЛО прилетело и опубликовало эту надпись здесь
+1
webwin #
0
egorinsk #
Чиатйте quirksmode, и поймете, где вы накосячили.
НЛО прилетело и опубликовало эту надпись здесь
–1
egorinsk #
Напписали же — надо смотреть свойства event.ctrlKey и иже с ними, а не keyCode
–1
TheShock #
егоринск, я вижу, что вы очень обознанны в этом деле. Но у меня сейчас уже реализовано с помощью ctrlKey и аналогов, но мне не нравится этот подход. почему — смотрите в исходниках. в топике про это сказано в пункте «3. Самое простое решение....»
0
Power #
А вы не пробовали смотреть на jQuery Hotkeys Plugin?
0
TheShock #
да, в прошлом топике обсуждали
+2
susanin #
Вы не поверите :)

Firefox
shift + ctrl — 16+17
ctrl + shift — 17+16
shift + alt — 16+18
alt + shift — 18+16
ctrl + alt — 17+18
alt + ctrl — 18+17

Chromium (местами ничего не переставлял, именно так и выводится)
shift + ctrl — 16+17
ctrl + shift — 16+17
shift + alt — 16+18
alt + shift — 16+18
ctrl + alt — 17+18
alt + ctrl — 17+18

Opera
shift + ctrl — 16+17
ctrl + shift — 17+16
shift + alt — 16+18
alt + shift — 18 + 16
ctrl + alt — 17+18
alt + ctrl — 18+17

Linux amelin 2.6.31-gentoo-r6
[ebuild R ] x11-base/xorg-server-1.6.5-r1
[ebuild R ] www-client/opera-10.10
[ebuild R ] www-client/chromium-bin-4.0.251.0_p32167
[ebuild R ] www-client/mozilla-firefox-3.5.5
[ebuild R ] kde-base/kdebase-meta-4.3.3
[ebuild R ] x11-drivers/xf86-input-evdev-2.3.1
НЛО прилетело и опубликовало эту надпись здесь
0
TheShock #
тот, что по-умолчанию в Кубунту 9.10. у меня обычная не хитровыеб не навороченная клавиатура.
если такая проблема только у меня, то это меня, в общем то, радует. но пути решения этой проблемы буду рад узнать.
НЛО прилетело и опубликовало эту надпись здесь
0
TheShock #
Хм… Это всё:
shock@shock:~$ ls /dev/input/by-id -l
итого 0
lrwxrwxrwx 1 root root 9 2009-11-27 14:47 usb-Genius_Optical_Mouse-event-mouse -> ../event4
lrwxrwxrwx 1 root root 9 2009-11-27 14:47 usb-Genius_Optical_Mouse-mouse -> ../mouse1
0
TheShock #
shock@shock:~$ sudo apt-get install xserver-xorg-input-evdev
[...]
Уже установлена самая новая версия xserver-xorg-input-evdev.
0
TheShock #
Section "InputDevice"
    Identifier "Keyboard0"
    Driver "evdev"
    Option "CoreKeyboard"
#   Option "Device" "/dev/input/event1"
    Option "XkbRules"   "xorg"
    Option "XkbLayout"  "us,ru(winkeys),ua(winkeys)"
    Option "XkbModel"   "evdev"
    Option "XkbOptions" "grp:ctrl_shift_toggle"
EndSection

Если строку Девайс не закомментировать ­— Иксы отказывались запускаться. Так — ничего не изменилось
НЛО прилетело и опубликовало эту надпись здесь
0
TheShock #
хм… какая-то странная ситуация… что за клавиатура? явно не USB предполагаю?

Genius w2036, PC/2, чёрненькая
НЛО прилетело и опубликовало эту надпись здесь
0
TheShock #
по-дефолту у меня был такой xorg.conf: pastebin.ru/308759
НЛО прилетело и опубликовало эту надпись здесь

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