【问题标题】:Single ESC closes ALL modal dialogs in jQuery UI. Workarounds?单个 ESC 关闭 jQuery UI 中的所有模式对话框。解决方法?
【发布时间】:2011-06-12 06:12:45
【问题描述】:

实际上,jQuery 中存在(仍然)一个错误:http://bugs.jqueryui.com/ticket/4511

此行为的原因(来自错误描述 cmets):“对话框本身将 keydown 事件绑定到自身以在 ESC 上关闭对话框;此外,对话框覆盖将 keydown 事件绑定到文档,无需过滤以仅关闭活动对话框。”

我想不出一个可接受的解决方法。有没有人不得不处理它?

【问题讨论】:

  • 不要同时显示多个 modal 对话框。这是糟糕的用户界面,可能是这个错误(实际上是这个错误的副本:bugs.jqueryui.com/ticket/3539)在 2 年内没有被触及的原因。
  • 我想不出更好的解决方案。这是相当标准的。我有一个 jqGrid,在单击某些单元格时会打开对象的历史记录(大多数情况下为 10-200 行),并带有提供一些操作的标题。每条历史消息都有“查看详细信息”。在这种情况下,将两个模态对话框堆叠在一起是很自然的。但我愿意接受建议...此外,第一个对话框上的操作可能会提示警告(例如,删除要求确认)
  • 尝试使用非模态对话框。在这里,“Esc”仅关闭最后打开的对话框(即使它在后台)。再次按 Esc 没有结果。但这可能是一种可行的方法,需要进行一些更改(仅打开一个相同类型的对话框,“手动”处理 Esc)。会试试看。

标签: javascript jquery-ui dialog keyboard-shortcuts modal-dialog


【解决方案1】:

非常简单 - 创建模式对话框后,运行以下命令:

$([document, window]).unbind('.dialog-overlay'); 

如果您创建多个模式对话框,点击 ESC 将仅关闭顶部的一个。 然后,一旦您专注于底部对话框,点击 ESC 它也会关闭它。

希望这有帮助!

附:当您希望在点击 ESC 键时立即关闭所有对话框或只关闭焦点对话框时,jQuery UI 开发人员应该添加一个选项。

【讨论】:

  • 感谢您回复那个!这个答案不是一个完整的解决方案,但可以解决问题。但是,它还可以防止在 tompost 被 ESC-ped 后 ESC-ping 较低的对话框。但它确实让我走上了正轨。我所做的解决方法将作为单独的答案发布。
  • “在 tompost 被 ESC-ped 后防止 ESC-ping 下部对话框” - 当然,只有在您在底部对话框上至少单击一次之前,这是正确的(Jazzer 在答案中说了这么多)。因此,对于正在寻找更简单解决方案的人来说,这一个班轮可以很好地工作。
  • 这也适用于回车吗?我有弹出窗口在另一个之上打开。如果我使用此代码,按 Enter 键将仅提交顶部弹出窗口还是全部?
【解决方案2】:

问题的根源在于 jQuery UI keydown 事件通过所有对话框传播。原始 jQueryUI 对话框代码中的一个修复方法是在最顶层对话框成功关闭时添加 event.stopPropagation(),并在同一 keydown 事件的开头检查 event.isPropagationStopped()

作为一种解决方法,我做了,感谢 Jazzer,以下。

  1. 将对话框选项closeOnEscape 设置为false

  2. 创建对话框后,追加:

    //newDialog is dialog's content, e.g. var newDialog = $('my dialog content>');
    newDialog.keydown(function(event) {
         if (mydialogs.hasOpenDialogs() && 
             event.keyCode && 
             event.keyCode === $.ui.keyCode.ESCAPE) {
                            $(newDialog).dialog("close");
                            event.preventDefault();
    event.stopPropagation(); } });

  3. 加载文档时执行以下操作:

    $(function(){
    //allow for ESC to close only top dialog
    $(document).bind('keydown', function(event) {
        if (event.isPropagationStopped()) return true;
        if (mydialogs.hasOpenDialogs() && 
            event.keyCode && 
            event.keyCode === $.ui.keyCode.ESCAPE) {
                            mydialogs.closeTopDialog();
                            event.preventDefault();
                            event.stopPropagation();
        }
    });
    });
    

(2) 中的事件发生在用户在对话框内的输入框中键入文本时点击 ESC。 (3) 中的事件发生在用户在其他地方点击 ESC 时。

mydialogs 这里是模态对话框堆栈(数组)的包装器,其中每个新对话框通过.push() 添加自己,在.close() 中通过.pop() 删除自己。

【讨论】:

    【解决方案3】:

    最简单的事情是我在 jquery.ui.dialog.js 文件中的 return self; 之前的关闭函数中添加了 event.stopPropagation();。我已经解决了在转义键下一个一个关闭对话框的问题。让我知道是否有人找到更好的解决方案。

    编辑: 这需要添加,因为单击关闭按钮事件对象时未定义。

    如果(事件类型!='未定义'){ event.stopPropagation(); }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-17
      • 1970-01-01
      相关资源
      最近更新 更多