Я борюсь с очень странным поведением JavaScript на виджете UI jQuery, который я пытаюсь зафиксировать. IE7 (выигрывают XP), jQuery 1.2.6 (да, это - старая версия).
Виджет является полем комбинированного списка, которое получает события клавиатуры и имеет специальные поведения для клавиш со стрелками.
Когда я пытаюсь ввести "и" символ в flexbox поле ввода, я получаю странное поведение.
flexbox имеет некоторый код как:
//initialization
$myInputElement.keypress($.flexbox.process_key);
$.flexbox.process_key = function process_key(e) {
$.flexbox.flexboxFromInput(this).processKey(e);
return true;
};
//on the flexbox object's prototype:
...
processKey: function processKey(e) {
var mod = 0;
if (typeof (e.ctrlKey) !== 'undefined') {
if (e.ctrlKey) mod |= 1;
if (e.shiftKey) mod |= 2;
} else {
if (e.modifiers & Event.CONTROL_MASK) mod |= 1;
if (e.modifiers & Event.SHIFT_MASK) mod |= 2;
}
...
switch (e.keyCode) {
case 38: // up
this.prevResult();
break;
case 40: // down
if (this.getCtr().is(':visible')) this.nextResult();
else this.flexboxDelay(true);
break;
...etc.
}
}
...
То, когда я представляю регистрирующийся оператор, что я нахожу, - то, что нажатие "и" (shift+7) производит три события нажатия клавиши:
INFO: Flexbox> processKey, keyCode=16, ctrl=false, shift=true
INFO: Flexbox> processKey, keyCode=55, ctrl=false, shift=true
INFO: Flexbox> processKey, keyCode=38, ctrl=false, shift=true
По-видимому, код клавиши 38 является и клавишей со стрелкой вверх и кодом ASCII для амперсанда??
Поскольку я писал это, мне пришло в голову, что я могу обнаружить нажатие клавиши как "shift+7" (код клавиши 55), чтобы рассматривать его как ключ амперсанда, затем установить некоторый флаг для игнорирования следующего нажатия клавиши (который является 38). Это походит на ужасный взлом.
У кого-либо есть лучший способ дифференцировать между специальными символами такой как "и" и клавиши со стрелками в IE?
Вот чем я закончил:
/*
* Hack around a wierd behavior in IE where "&%'(" have the same keyCodes
* as the arrow keys.
*/
if (keyCodeIn(e.keyCode, 55, 53, 57) && (mod & 2) && !(mod & 1)) {
this.ignoreNextArrowKey = true;
}
else if (222 === e.keyCode && !(mod & 2) && !(mod & 1)) {
this.ignoreNextArrowKey = true;
}
else if (keyCodeIn(e.keyCode, 38, 37, 39, 40) && this.ignoreNextArrowKey) {
this.ignoreNextArrowKey = false;
return;
}
//...
function keyCodeIn(keyCode) {
for(var i = 1; i < arguments.length; i++) {
if (arguments[i] === keyCode) {
return true;
}
}
return false;
}
Надеюсь, это кому-то поможет. Если вы повторно используете этот код, вам, возможно, придется скорректировать использование ключевого слова this, в зависимости от того, к какому объекту оно относится (здесь это объект javascript, связанный с виджетом flexbox).
Редактировать: Я обновил этот код и удалил тест регулярных выражений, который был там ранее, но обнаружил, что в нем есть ошибки.
Я думаю, что keydown
может дать вам более надежные данные, чем keypress
.
key up или down возвращает keyCode 55 для '&' и 38 для 'Arrow Up'
Я рекомендую использовать эту библиотеку jquery для написания пользовательских обработчиков нажатий клавиш: http://code.google.com/p / js-hotkeys /
Попытка определить коды клавиш логически - это кошмар.