適切な調査と試行錯誤の後、ここでの最善/唯一の解決策は、独自のカスタム フォーム コントロールを作成することのようです。
以下は、問題を解決するための失敗した試みです。
http://jsfiddle.net/CoryDanielson/4jBgs/10/
これが基本的にどのように機能するかです。
まず、ユーザーが注目している入力activeInput
を格納する変数があります。DOMElement
(入力がエスケープ可能な場合のみ)
var activeInput = false;
この変数を設定するために、あなたが言及したDOMElementsの配列を作成しましたescaped
(オートコンプリート、選択要素のあるテキストボックス)
var escapableElements = [];
escapableElements = escapableElements.concat(
Array.prototype.slice.call(document.getElementsByTagName('select')),
Array.prototype.slice.call(document.getElementsByTagName('input'))
//add more elements here
);
次に、配列をループしてand (フォーカスを失う) イベントにアタッチeventListeners
します。(この投稿の下部に for each 関数を含めました)focus
blur
forEach(escapableElements, function() {
this.addEventListener('focus', registerActiveElement);
this.addEventListener('blur', deregisterActiveElement);
});
function registerActiveElement() {
if (!activeInput)
activeInput = this;
//console.log('registered'); //testing only
}
function deregisterActiveElement() {
if (activeInput)
activeInput = false;
//console.log('deregistered'); //testing only
}
その後、イベントeventListener
用に配線しました。keydown
その中に、あるactiveInput
場合return true;
はブラウザが必要なことを実行できるかどうかを確認しました(オートコンプリートからのエスケープなど)がない場合は、押されたactiveInput
かどうかを確認して呼び出しますESC
hide_dialog_box(event.keyCode);
キープレスの処理に関する質問の段落との唯一の違いは、事前ESC
にあったかどうかを確認したことです。activeInput
がある場合activeInput
、私は何もしませんでした (ブラウザーに ESC をネイティブに処理させます) ない場合は、ブラウザーの ESC のネイティブ処理をキャンセルし、関数をactiveInput
呼び出してから、ブラウザーがキープレスを処理するのを防ぐのにも役立ちます。event.preventDefault()
hide_dialog_box(keyCode)
return false;
ESC
document.addEventListener('keydown', function(event) {
if (!activeInput) {
if (event.keyCode == 27) { //esc
event.preventDefault();
hide_dialog_box(event.keyCode);
return false;
}
} else {
return true; //if active input, let browser function
}
/*
if the browser prompts with an autocomplete menu for
<input type="text">, or options on a <select> drop down
pressing escape will cancel that, not cancel the dialog.
*/
});
コードの最後の 2 つのスニペットは、関数と、呼び出されhide_dialog_box(keyCode)
た関数をループするために書いた関数です。NodeList
escapableElements
function hide_dialog_box(keyCode) {
var dialog_box = document.getElementById('dialog_box');
dialog_box.style.display = 'none';
}
function forEach(list, callback) {
for (var i = 0; i < list.length; i++)
{
//calls the callback function, but places list[i] as the 'this'
callback.call(list[i]);
}
}