jQuery UI对话框绑定keydown并不总是有效

时间:2014-03-03 18:41:01

标签: jquery-ui backbone.js jquery-ui-dialog backbone-views keydown

我正在编写自己的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事件吗?

修改

我刚注意到这也发生在一些第一级对话框中。看起来唯一的区别是我们获取模板的方式,因此创建了对话框的内部。在我们的AlertConfirmation对话框类中,我们将模板定义为对象的属性,如下所示: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?

2 个答案:

答案 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();
    }
  });
}