如何截获jQuery对话框ESC键事件?
我有一个模态jQuery对话框和另一个元素,它在对话框后面接受ESC键事件。当jQuery对话框打开时,我不希望此ESC键事件传播。现在发生的是,当我单击ESC时,它将关闭对话框并在后台元素上触发ESC事件处理程序如何截获jQuery对话框ESC键事件?,jquery,jquery-ui,jquery-ui-dialog,Jquery,Jquery Ui,Jquery Ui Dialog,我有一个模态jQuery对话框和另一个元素,它在对话框后面接受ESC键事件。当jQuery对话框打开时,我不希望此ESC键事件传播。现在发生的是,当我单击ESC时,它将关闭对话框并在后台元素上触发ESC事件处理程序 当jQuery对话框被取消时,我如何处理ESC键事件?您需要修改对话框后面元素的代码,以查看对话框是否打开,是否按了escape键,并忽略该情况。您需要closeOnEscape 示例代码: $(function() { $("#popup").dialog({ height: 20
当jQuery对话框被取消时,我如何处理ESC键事件?您需要修改对话框后面元素的代码,以查看对话框是否打开,是否按了escape键,并忽略该情况。您需要closeOnEscape 示例代码:
$(function() {
$("#popup").dialog({
height: 200,
width: 400,
resizable: false,
autoOpen: true,
modal: true,
closeOnEscape: false
});
});
现场查看:在内部,jQuery UI的对话框的
closeOnEscape
选项是通过在文档本身附加一个按键侦听器来实现的。因此,一旦keydown事件一直冒泡到顶层,对话框就会关闭
因此,如果希望继续使用escape键关闭对话框,并且希望escape键不会传播到父节点,则需要自己实现closeOnEscape
功能,并在事件对象上使用stopPropagation
方法(请参阅)
这样做的目的是侦听对话框中发生的所有键控事件。如果按下的键是escape键,则可以按正常方式关闭对话框,并且无论使用什么evt.stopPropagation
调用,都可以防止向下键冒泡到父节点
我这里有一个活生生的例子-。您可以使用以下
$(document).keyup(function (e) {
if (e.keyCode == 27) {
$('#YourDialogID').dialog('close')
}
});
我想做一件类似但相反的事情——如果在对话框仍然打开时,在对话框内部打开的模式窗口中按ESC键,则阻止ui对话框关闭 因此,如果模式窗口在ui对话框顶部打开,则ESC只能关闭模式窗口并保持ui对话框打开。我不想为对话框禁用closeOnEscape,只要在另一个模式打开时抑制它即可 我对jquery-ui-1.12.1中的$(document).on(“keydown”、…)或$dialog.on(“keydown”、…)不感兴趣。我调用widget方法_off和_on来删除原始的keydown事件,并将其替换为我自己的截取事件,在截取事件中,我可以不执行任何操作,也可以运行原始的处理程序代码 也许有一种更优雅的方法可以调用原始的keydown事件而不复制代码,但我还没有弄明白这一点 在使用$dialog.dialog(…)创建PatchCloseOnEscape之后,我调用它($dialog)
/**
*当我们按ESC键关闭jQueryUI对话框时,需要避免关闭该对话框
*对话框仍处于打开状态时从对话框打开的模式窗口。
*/
私有静态PatchCloseOnEscape($dialog:JQuery):void
{
//获取对话框小部件
let dialog=$dialog.data(“ui dialog”);
//删除原始的keydown事件
对话框。_关闭(dialog.uiDialog,“键控”);
//添加我们新的keydown事件
对话框。打开(dialog.uiDialog{
向下键:功能(事件)
{
//仅当模式窗口未显示时,在退出时关闭。
如果(=真)
{
返回;
}
////////////////////////////////////////////////////////////////////////////////
//从jquery-ui-1.12.1.js第12278-12305行中的原始keydown事件复制而来
if(this.options.closeOnEscape&&!event.isDefaultPrevented()&&event.keyCode&&
event.keyCode==($).ui.keyCode.ESCAPE)
{
event.preventDefault();
本次会议结束(活动);
返回;
}
//防止跳出对话框
if(event.keyCode!==($).ui.keyCode.TAB | | event.isDefaultPrevented())
{
返回;
}
var tabbables=this.uiDialog.find(“:tabbable”),
first=tabbables.filter(“:first”),
last=tabbables.filter(“:last”);
if((event.target==last[0]| | event.target==this.ui对话框[0])&&
!event.shiftKey)
{
此延迟(函数()
{
第一,触发(“焦点”);
});
event.preventDefault();
}else if((event.target==first[0]||
event.target==this.uiDialog[0])&&event.shiftKey)
{
此延迟(函数()
{
最后。触发(“焦点”);
});
event.preventDefault();
}
////////////////////////////////////////////////////////////////////////////////
}
});
}
。您的方式将删除按escape关闭对话框的功能。我编辑了样式标记,因此仍然有一个“关闭”链接可用。仍然不是最终的解决方案。谢谢你的回答。但问题是,当我按下ESC键时,事件首先进入对话框并关闭对话框。然后它会转到我的背景元素,此时它会发现对话框不在那里,并接受ESC事件。那么在对话框打开时从背景元素中删除侦听器,然后在对话框关闭后重新附加它怎么样?我想这会起作用,但这不是有点不正常吗?有没有一种不太老套的方法呢?这不管用,我在你的JSFIDLE中的keydown函数中添加了一个简单的警报,它永远不会被调用:(不幸的是closeOnEscape对我不起作用。但是这种绑定起到了作用。如果对话框上没有“input”元素,或者如果焦点离开该元素而在实际的对话框上,这种绑定就不起作用。你需要用parent将keydown绑定到上面的元素,所以你需要更改“.on('keydown')b
$(document).keyup(function (e) {
if (e.keyCode == 27) {
$('#YourDialogID').dialog('close')
}
});
/**
* 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();
}
////////////////////////////////////////////////////////////////////////////////
}
});
}