РЕДАКТИРОВАТЬ: Поскольку никто не ответил, я постараюсь изложить свой вопрос более кратко. При обработке нажатий клавиш на странице браузера (например, влево / вправо / пробел), как определить, будет ли нажатие клавиши обрабатываться элементом на странице браузера, который имеет фокус или будет ли не обрабатываться этим объектом, и будет ли нормально обрабатывать его глобально? В идеале вы должны позволить объекту фокусировки видеть нажатие клавиши и иметь возможность определить, обрабатывал ли он его или нет. Если нет, то вы можете обработать это самостоятельно. Если бы он обрабатывал это, вы бы ничего с этим не делали (предполагая, что объект фокусировки имеет более важное использование для нажатия клавиш).
Вот типичный пример не в браузере. Представьте, что у вас есть диалоговое окно Windows, в котором есть набор типичных элементов управления диалогового окна, пара кнопок и богатый элемент управления для редактирования. Если вы находитесь в типичном диалоговом окне, клавиша Enter на клавиатуре активирует кнопку OK в диалоговом окне и примет изменения в диалоговом окне. Если вы находитесь в элементе управления rich edit, клавиша Enter вводит новую строку. Диалоговое окно каким-то образом может сказать, хочет ли текущий элемент управления в диалоговом окне обработать клавишу ввода или он должен обрабатываться глобально.
В моем конкретном случае с браузером я использую обработку событий YUI2 для захвата нажатий клавиш на уровне документа, чтобы позволить пользователю использовать стрелки влево / вправо на клавиатуре для перемещения по слайд-шоу на странице без необходимости явно установить фокус на любой конкретный элемент на странице (функция, которая нравится моим пользователям). Но если на странице есть какие-либо редактируемые поля, я хочу, чтобы эти стрелки влево / вправо обрабатывались этим полем на странице, а не моим слайд-шоу. Я ищу элегантный способ сделать это.
Я понимаю, что могу посмотреть на исходную цель события и «попытаться» выяснить, способна ли эта цель обрабатывать стрелки влево / вправо (ввод, текстовое поле, contenteditable и т. Д.), Но я надеялся на более надежный метод. Есть ли способ обрабатывать нажатие клавиш на уровне документа ТОЛЬКО тогда, когда он не обрабатывается объектом на веб-странице. Теперь в моем обработчике клавиатуры YUI я получаю все события клавиатуры, даже те, которые фактически будут обрабатываться целевым объектом.
Вот как теперь выглядит мой код, и я ищу более элегантный способ сделать это, не требующий функции ObjectWantsKeys, которая является несколько хрупкой:
JF.Slideshow.prototype._HookupKeyNav = function () {
var k = YAHOO.util.KeyListener;
var key = k.KEY;
// see if keyboard handling is enabled or not
if (((this._config.keyboardNav == "auto") && (JF.SlideshowCnt <= 1)) || (this._config.keyboardNav == "on")) {
this._keyListener = new YAHOO.util.KeyListener(
document, {
ctrl: false,
shift: false,
alt: false,
keys: [key.LEFT, key.RIGHT, key.SPACE]
}, {
fn: this._HandleKeys,
scope: this,
correctScope: true
});
this._keyListener.enable();
}
}
JF.Slideshow.prototype._HandleKeys = function (type, args, obj) {
var keyCode = args[0];
var event = args[1];
var target = event.srcElement || event.target;
if (JFL.ObjectWantsKeys(target)) return; // if the current focus object wants keystrokes, then we shouldn't process them
var key = YAHOO.util.KeyListener.KEY;
switch (keyCode) {
case key.LEFT:
this.Back();
break;
case key.RIGHT:
this.Forward();
break;
case key.SPACE:
this.StartStopToggle();
break;
default:
break;
}
}
JFL.ObjectWantsKeys = function (o) {
// list of HTML object types that want the keystroke if they have focus
var list = {
"input": true,
"textarea": true
};
try {
// unfortunately o.contentEditable set to an empty string means it is editable so we need this more complicated comparision
if ((typeof o.contentEditable !== "undefined") && (o.contentEditable === "true" || o.contentEditable === true || o.contentEditable === "")) {
return (true); // focus object is editable
}
if (o.tagName && list[o.tagName.toLowerCase()]) {
return (list[o.tagName.toLowerCase()]); // focus object can take keys
}
} catch (e) {}
return (false);
}