失去焦点时销毁对话框

时间:2012-09-13 08:10:09

标签: jquery jquery-ui jquery-ui-dialog

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

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

当我有一个对话框并将focusinfocusout附加到包含对话框的元素(我称之为dialog的元素的父元素)时。对话框出现后的第一次单击始终会产生focusout事件,无论点击的位置如何。

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

我知道我可以使用一些技巧来忽略第一个focusout,但我想知道是否有任何方法可以使这个工作正确,这是唯一的事件是在用户第一次在对话框外点击。

更新

我在underscore.js的帮助下找到了对我的问题的回答:

我将问题分解为部分:

  1. 首次点击时发生focusout
  2. 如果点击是在对话框外面,则没有其他事件
  3. 如果点击是在对话框中,则跟随<{1}}事件
  4. 因此,当存在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之后onFocusinonFocusout变为hasFocus并且延迟函数不会破坏对话框,那么true就会被触发!

    感谢您的回答!

5 个答案:

答案 0 :(得分: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');
    }
});

Demo

答案 1 :(得分:1)

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

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

它就像一个魅力:)

答案 2 :(得分:0)

模糊应该适合你:

$('.dialog').trigger('click');
$('.dialog').blur(function() {
   this.dialog('destroy');
}

答案 3 :(得分:0)

这是我的解决方法,它在一个包含多个对话框的页面中工作,也更新了jquery'live'方法的解决方案:

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

我受Scott's answer

的启发

答案 4 :(得分:0)

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

$(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");
});