15

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

当 jQuery 对话框被解除时,我如何吃掉 ESC 键事件?

4

5 回答 5

23

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

因此,如果您想继续使用转义键关闭对话框,并且希望阻止转义键传播到父节点,则需要自己实现该closeOnEscape功能以及使用stopPropagation事件对象上的方法(请参阅有关 event.stopPropagation 的 MDN 文章)。

(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/

于 2012-05-06T12:38:06.697 回答
19

你需要closeOnEscape ...

示例代码:

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

现场观看:http: //jsfiddle.net/vutdV/

于 2012-05-05T23:27:16.953 回答
5

您可以使用以下

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

            $('#YourDialogID').dialog('close')  
        }
    });
于 2013-11-18T11:30:16.637 回答
0

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

于 2012-05-05T23:14:50.603 回答
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();
            }

            ////////////////////////////////////////////////////////////////////////////////
        }
    });
}
于 2020-08-12T13:28:48.690 回答