1

我有一个程序,其中有 jQuery UI 对话框。我希望这些对话框在失去焦点时关闭,例如用户单击相关对话框之外的任何位置。

从表面上看,这似乎是一个简单的问题,但blur事件根本不起作用。之后我转到focusinand focusout,但偶然发现了一个奇怪的问题:

当我有一个对话框并附加到包含对话框focusinfocusout元素(我调用的元素的父级dialog)时。对话框出现后的第一次点击总是会产生一个focusout事件,无论点击在哪里。

因此,如果我想在 上销毁对话框focusout,则对话框会在不应该被销毁的时候被销毁。这是jsFiddle演示了我的问题。

我知道我可以使用一些技巧来忽略第一个focusout,但我想知道是否有任何方法可以让它以正确的方式工作,即当用户在对话框外部单击第一个时会产生唯一的事件时间。

更新:

在以下帮助下,我找到了对我的问题的满意答案underscore.js

我把我的问题分解成几个部分:

  1. Afocusout在第一次点击时发生
  2. 如果点击在对话框之外,则没有进一步的事件
  3. 如果单击是在对话框内,则发生focusin事件

因此,当有一系列focusout->时,就会发生不良行为focusin。我使用下划线defer函数和布尔修饰符来解决这个问题

onFocusout: function(event) {
  console.log('focus out');
  this.hasFocus = false;
  var self = this;
  _.defer(function() {
    if (!self.hasFocus) alert('DESTROY DIALOG');
  });
},

onFocusin: function() {
  console.log('focus in');
  this.hasFocus = true;
},

defer使函数等待直到调用堆栈被清除(在不良行为情况下,focusin堆栈中有一个事件等待)然后执行它。因此,如果在变量更改为onFocusin之后立即触发,并且延迟函数不会破坏对话框!onFocusouthasFocustrue

谢谢您的回答!

4

5 回答 5

6

一个可能效果更好的选项是侦听页面上任何位置的点击,如果点击出现在对话框区域之外,则关闭对话框。就像是:

$(document).on("click", function(e) {
    var clickedOnDialog = $(e.srcElement)
         .closest(".ui-widget.ui-dialog") // these classes are fixed
         .children(".ui-dialog-content") // this as well
         .is(".dialog"); // this is your own class

    if (!clickedOnDialog) {
        $('.dialog').dialog('destroy');
    }
});

演示

于 2012-09-13T08:18:21.237 回答
1

ui-widget-overlay仅供参考,对于 jQuery 模态对话框,它会在您的内容顶部放置一个带有类的 div 。因此,我只是做了这样的事情:

$(".ui-widget-overlay").live("click", function() {
    $("#myDialogDiv").dialog("close");
});

它就像一个魅力:)

于 2012-12-13T19:51:24.557 回答
0

这是我的解决方法,它也适用于具有多个对话框的页面,还更新了 jquery 'live' 方法的解决方案:

$(document).on('click', '.ui-widget-overlay', function() {
    var dialogAria = $(this).next().attr('aria-describedby');        
    $('#'+dialogAria).dialog("close");
});

我受到斯科特的回答的启发

于 2013-04-04T12:18:21.860 回答
0

模糊应该适合你:

$('.dialog').trigger('click');
$('.dialog').blur(function() {
   this.dialog('destroy');
}
于 2012-09-13T08:40:18.433 回答
0

使用 jQuery,这相当简单。jQuery 构建其对话框的方式是,每当一个对话框变为活动状态时,它都会放置一个 div 覆盖所有其他页面内容,并具有一个 .ui-widget-overlay 类,并且它的 z-index 为 x(在我的案例,100)。每当一个对话框变为活动状态时,它都会给那个对话框,并且那个对话框只有一个 x + 1 的 z-index。

$(document).on('click', '.ui-widget-overlay', function () {
    var overlay = $(this);
    var dialogToClose = null;
    $.each($(".dialog"), function () {
        if ($(this).zIndex() == (overlay.zIndex() + 1)){
            dialogToClose = $(this);
        }
    });
    dialogToClose.dialog("close");
});
于 2015-06-08T16:56:57.560 回答