我正在编写自己的ESC处理程序,因为我需要在按下ESC时执行其他操作,特别是我需要管理专注于仅键盘用户的重点。我有它适用于所有菜单和一些对话框(两者都使用jQueryUI)但我遇到了在其他对话框(确认对话框)之上打开的对话框的问题。
我正在使用Backbone View并在dialogcreate
上添加我的keydown处理程序。 this.$el.on('dialogcreate', this.bindKeydownEvent);
我的经纪人:
bindKeydownEvent: function(ev, ui) {
var self = this;
this.$el.dialog().on('keydown', function(evt) {
if(evt.keyCode === $.ui.keyCode.ESCAPE) {
self.$el.dialog("close");
if(self.options.closeFocusEl) {
$(self.options.closeFocusEl).focus();
}
evt.stopPropagation();
}
});
}
当第二个对话框调用this.$el.dialog()
时,我检查了this.bindKeydownEvent
是正确的对话框但是由于某种原因,无论我在对话框中按什么都没有触发keydown处理程序(Tab,Space) ,输入,随机字母等)。
知道我做错了什么或者有更好的方法我可以绑定keydown事件吗?
修改
我刚注意到这也发生在一些第一级对话框中。看起来唯一的区别是我们获取模板的方式,因此创建了对话框的内部。在我们的Alert
和Confirmation
对话框类中,我们将模板定义为对象的属性,如下所示:template: _.template("<div><%= o.content %></div>")
。在其他视图中(keydown绑定工作)我们构建子元素并将它们添加到对话框的DOM中,在初始化函数中设置模板
this.options.template = 'navigation/CreateNewDialog.template';
或在我们调用对话框时设置它
var closeConv = new views.CloseConversationDialogView({
confirm: this.closeConversationConfirmed,
content: i18n.t("closeConversationInput"),
template: "conversation/CloseConversationDialog.template"
});
closeConv.render();
是否有理由将视图中的属性作为内联创建模板不能正确绑定keydown?
答案 0 :(得分:1)
要了解未触发事件处理程序的原因,首先需要了解事件委派的工作原理。
事件中事件委派的关键冒泡在DOM中。因此,当您使用this.$el.dialog().on('keydown',...
绑定事件时,您基本上所做的就是收听keydown
或其后代触发的任何$el
事件。在这种情况下,您的第二个对话框不是$el
的后代,它的事件不会冒泡到它,因此不会触发您的处理程序。
要解决此问题,您可以直接绑定到第二个对话框,也可以绑定到文档等现有的更高级别元素。例如
$(document).on('keydown', '.myDialog', function() {...
答案 1 :(得分:1)
我唯一缺少的是“小部件”。根据{{3}},
,widget
方法
返回包含生成的包装器的jQuery对象。
我没有看到有关$('.selector').dialog()
确切返回的文档,但显然它与$('.selector').dialog("widget")
不同。我还将on('keydown'...
更改为仅使用jQuery keydown
。
bindKeydownEvent: function(ev, ui) {
var self = this;
this.$el.dialog("widget").keydown(function(evt) {
if(evt.keyCode === $.ui.keyCode.ESCAPE) {
self.$el.dialog("close");
if(self.options.closeFocusEl) {
$(self.options.closeFocusEl).focus();
}
evt.stopPropagation();
}
});
}