Support for canceling the DHTML exit dialog box

Introduce the DHTML dialog box with the following markup:

<div id="someDialog" class="dialog">
    <h2>Title of dialog</h2>

    Lots: <input ...>
    of: <select ...>
    controls: <textarea ...>

    <input type="submit" value="OK">
    <input type="reset" value="Cancel">
</div>

The user will cancel the dialog. This in itself is not complicated - just add a keydown event handler to document.documentElement to check ev.keyCode == 27, and use this to close the topmost dialog box on the page.

The problem is that there are certain circumstances where it is important that the browser first detects the escape key. For example, if the browser requests an autocomplete menu for <input type="text">, pressing escape should cancel this, and not cancel the dialog. If you select the drop-down menu for <select>, pressing escape should close this, not the dialog.

, , -?


: Exchange . " , ?" link, DHTML, , alt-down, , , , . . .

+3
1

/, / , , .


.

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
);

eventListeners 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;, , ( ..), IS NOT a activeInput, ESC hide_dialog_box(event.keyCode);

ESC , , activeInput. activeInput, ( ESC ), activeInput, event.preventDefault(), ESC 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]);
    }
}
+2

All Articles