如何拦截jQuery Dialog ESC键事件?

时间:2012-05-05 23:12:07

标签: jquery jquery-ui jquery-ui-dialog

我有一个模态jQuery对话框和另一个在对话框后面接受ESC键事件的元素。当jQuery对话框启动时,我不希望传播这个ESC键事件。现在发生的是当我点击ESC时,它将关闭对话框并触发背景元素上的ESC事件处理程序。

如果解除jQuery对话框,我该如何吃ESC键事件?

5 个答案:

答案 0 :(得分:20)

内部jQuery UI的对话框closeOnEscape选项是通过将keydown侦听器附加到文档本身来实现的。因此,一旦keydown事件一直冒泡到顶层,对话框就会关闭。

因此,如果您希望继续使用转义键来关闭对话框,并且希望保持转义键不会传播到父节点,则需要自己实现closeOnEscape功能以及制作在事件对象上使用stopPropagation方法(请参阅MDN article on event.stopPropagation)。

(function() {
  var dialog = $('whatever-selector-you-need')
    .dialog()
    .on('keydown', function(evt) {
        if (evt.keyCode === $.ui.keyCode.ESCAPE) {
            dialog.dialog('close');
        }                
        evt.stopPropagation();
    });
}());

这样做是为了侦听对话框中发生的所有keydown事件。如果按下的键是转义键,则按正常方式关闭对话框,无论evt.stopPropagation调用是什么使keydown不会冒泡到父节点。

我在这里展示了一个实例 - http://jsfiddle.net/ud9KL/2/

答案 1 :(得分:18)

你需要closeOnEscape ......

示例代码:

$(function() {
$("#popup").dialog({
height: 200,
width: 400,
resizable: false,
autoOpen: true,
modal: true,
closeOnEscape: false
});
});

现场直播:http://jsfiddle.net/vutdV/

答案 2 :(得分:4)

您可以使用以下

    $(document).keyup(function (e) {
        if (e.keyCode == 27) {

            $('#YourDialogID').dialog('close')  
        }
    });

答案 3 :(得分:0)

您需要修改对话框后面元素的代码,以查看对话框是否已打开并按下了转义键并忽略该情况。

答案 4 :(得分:0)

我想做类似但相反的事情-如果在对话框仍处于打开状态时从对话框内部打开的模式窗口中按ESC,则防止ui对话框关闭。

因此,如果在ui对话框顶部打开了模式窗口,则ESC必须仅关闭模式窗口并使ui对话框保持打开状态。我不想禁用该对话框的closeOnEscape,只要在其上打开了另一个模态就不要显示它。

我对jquery-ui-1.12.1中的$(document).on(“ keydown”,...)或$ dialog.on(“ keydown”,...)不满意。我将小部件方法_off和_on调用,以使用我自己的拦截事件删除并替换原始的keydown事件,在该事件中,我什么也不做或运行原始的处理程序代码。

也许有一种更优雅的方式来调用原始的keydown事件而不重复代码,但是我还没有弄清楚。

在使用$ dialog.dialog(...)创建它之后,我立即调用PatchCloseOnEscape($ dialog)。

/**
 * Tedium required to prevent the jQuery-UI dialog closing when we hit the ESC key to close
 * a modal window opened from the dialog while the dialog is still open.
 */
private static PatchCloseOnEscape($dialog: JQuery): void
{
    // Get dialog widget
    let dialog = $dialog.data("ui-dialog");

    // Remove original keydown event
    dialog._off(dialog.uiDialog, "keydown");

    // Add our new keydown event
    dialog._on(dialog.uiDialog, {
        keydown: function (event)
        {
            // Only close on escape if a modal window is not showing.
            if (<check if modal window is open> == true)
            {
                return;
            }

            ////////////////////////////////////////////////////////////////////////////////
            // Copied from original keydown event in jquery-ui-1.12.1.js line 12278 - 12305

            if (this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
                event.keyCode === (<any>$).ui.keyCode.ESCAPE)
            {
                event.preventDefault();

                this.close(event);

                return;
            }

            // Prevent tabbing out of dialogs
            if (event.keyCode !== (<any>$).ui.keyCode.TAB || event.isDefaultPrevented())
            {
                return;
            }
            var tabbables = this.uiDialog.find(":tabbable"),
                first = tabbables.filter(":first"),
                last = tabbables.filter(":last");

            if ((event.target === last[0] || event.target === this.uiDialog[0]) &&
                !event.shiftKey)
            {
                this._delay(function ()
                {
                    first.trigger("focus");
                });
                event.preventDefault();
            } else if ((event.target === first[0] ||
                event.target === this.uiDialog[0]) && event.shiftKey)
            {
                this._delay(function ()
                {
                    last.trigger("focus");
                });
                event.preventDefault();
            }

            ////////////////////////////////////////////////////////////////////////////////
        }
    });
}