Javascript jQuery UI - 在外部单击时关闭对话框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2554779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 00:53:24  来源:igfitidea点击:

jQuery UI - Close Dialog When Clicked Outside

javascriptjqueryjquery-uijquery-ui-dialog

提问by Sonny

I have a jQuery UI Dialog that gets displayed when specific elements are clicked. I would like to close the dialog if a click occurs anywhere other than on those triggering elements or the dialog itself.

我有一个 jQuery UI 对话框,单击特定元素时会显示该对话框。如果在这些触发元素或对话框本身以外的任何地方发生点击,我想关闭对话框。

Here's the code for opening the dialog:

这是打开对话框的代码:

$(document).ready(function() {
    var $field_hint = $('<div></div>')
        .dialog({
            autoOpen: false,
            minHeight: 50,
            resizable: false,
            width: 375
        });

    $('.hint').click(function() {
        var $hint = $(this);
        $field_hint.html($hint.html());
        $field_hint.dialog('option', 'position', [162, $hint.offset().top + 25]);
        $field_hint.dialog('option', 'title', $hint.siblings('label').html());
        $field_hint.dialog('open');
    });
    /*$(document).click(function() {
        $field_hint.dialog('close');
    });*/
});

If I uncomment the last part, the dialog never opens. I assume it's because the same click that opens the dialog is closing it again.

如果我取消对最后一部分的注释,对话框将永远不会打开。我认为这是因为打开对话框的相同点击再次关闭它。



Final Working Code
Note: This is using the jQuery outside eventsplugin

最终工作代码
注意:这是使用jQuery 外部事件插件

$(document).ready(function() {
    // dialog element to .hint
    var $field_hint = $('<div></div>')
            .dialog({
                autoOpen: false,
                minHeight: 0,
                resizable: false,
                width: 376
            })
            .bind('clickoutside', function(e) {
                $target = $(e.target);
                if (!$target.filter('.hint').length
                        && !$target.filter('.hintclickicon').length) {
                    $field_hint.dialog('close');
                }
            });

    // attach dialog element to .hint elements
    $('.hint').click(function() {
        var $hint = $(this);
        $field_hint.html('<div style="max-height: 300px;">' + $hint.html() + '</div>');
        $field_hint.dialog('option', 'position', [$hint.offset().left - 384, $hint.offset().top + 24 - $(document).scrollTop()]);
        $field_hint.dialog('option', 'title', $hint.siblings('label').html());
        $field_hint.dialog('open');
    });

    // trigger .hint dialog with an anchor tag referencing the form element
    $('.hintclickicon').click(function(e) {
        e.preventDefault();
        $($(this).get(0).hash + ' .hint').trigger('click');
    });
});

采纳答案by PetersenDidIt

Check out the jQuery Outside Events plugin

查看jQuery 外部事件插件

Lets you do:

让你做:

$field_hint.bind('clickoutside',function(){
    $field_hint.dialog('close');
});

回答by stumac85

Sorry to drag this up after so long but I used the below. Any disadvantages? See the open function...

很抱歉拖了这么久,但我使用了下面的。有什么缺点吗?看到打开的功能...

$("#popup").dialog(
{
    height: 670,
    width: 680,
    modal: true,
    autoOpen: false,
    close: function(event, ui) { $('#wrap').show(); },
    open: function(event, ui) 
    { 
        $('.ui-widget-overlay').bind('click', function()
        { 
            $("#popup").dialog('close'); 
        }); 
    }
});

回答by Jason

Forget using another plugin:

忘记使用另一个插件:

Here are 3 methods to close a jquery UI dialog when clicking outside popin:

以下是在 popin 外部单击时关闭 jquery UI 对话框的 3 种方法:

If the dialog is modal/has background overlay: http://jsfiddle.net/jasonday/6FGqN/

如果对话框是模态的/有背景覆盖:http: //jsfiddle.net/jasonday/6FGqN/

jQuery(document).ready(function() {
    jQuery("#dialog").dialog({
        bgiframe: true,
        autoOpen: false,
        height: 100,
        modal: true,
        open: function(){
            jQuery('.ui-widget-overlay').bind('click',function(){
                jQuery('#dialog').dialog('close');
            })
        }
    });
}); 

If dialog is non-modal Method 1: method 1: http://jsfiddle.net/jasonday/xpkFf/

如果对话框是非模态方法1:方法1:http: //jsfiddle.net/jasonday/xpkFf/

 // Close Pop-in If the user clicks anywhere else on the page
                     jQuery('body')
                      .bind(
                       'click',
                       function(e){
                        if(
                         jQuery('#dialog').dialog('isOpen')
                         && !jQuery(e.target).is('.ui-dialog, a')
                         && !jQuery(e.target).closest('.ui-dialog').length
                        ){
                         jQuery('#dialog').dialog('close');
                        }
                       }
                      );

Non-Modal dialog Method 2: http://jsfiddle.net/jasonday/eccKr/

非模态对话框方法2:http: //jsfiddle.net/jasonday/eccKr/

  $(function() {
            $( "#dialog" ).dialog({
                autoOpen: false, 
                minHeight: 100,
                width: 342,
                draggable: true,
                resizable: false,
                modal: false,
                closeText: 'Close',
                  open: function() {
                      closedialog = 1;
                      $(document).bind('click', overlayclickclose);
                  },
                  focus: function() {
                      closedialog = 0;
                  },
                  close: function() {
                      $(document).unbind('click');
                  }



        });

         $('#linkID').click(function() {
            $('#dialog').dialog('open');
            closedialog = 0;
        });

         var closedialog;

          function overlayclickclose() {
              if (closedialog) {
                  $('#dialog').dialog('close');
              }

              //set to one because click on dialog box sets to zero
              closedialog = 1;
          }


  });

回答by Michele Locati

Just add this global script, which closes all the modal dialogs just clicking outsite them.

只需添加此全局脚本,只需单击它们的外部即可关闭所有模式对话框。

$(document).ready(function()
{
    $(document.body).on("click", ".ui-widget-overlay", function()
    {
        $.each($(".ui-dialog"), function()
        {
            var $dialog;
            $dialog = $(this).children(".ui-dialog-content");
            if($dialog.dialog("option", "modal"))
            {
                $dialog.dialog("close");
            }
        });
    });;
});

回答by jk.

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

Fiddleshowing the above code in action.

小提琴显示上面的代码在行动。

回答by Jerph

I had to do two parts. First the outside click-handler:

我必须做两部分。首先是外部点击处理程序:

$(document).on('click', function(e){
    if ($(".ui-dialog").length) {
        if (!$(e.target).parents().filter('.ui-dialog').length) {
            $('.ui-dialog-content').dialog('close');
        }
    }
}); 

This calls dialog('close')on the generic ui-dialog-contentclass, and so will close alldialogs if the click didn't originate in one. It will work with modal dialogs too, since the overlay is not part of the .ui-dialogbox.

这会调用dialog('close')通用ui-dialog-content类,因此如果单击不是源自一个对话框,则会关闭所有对话框。它也适用于模态对话框,因为覆盖不是.ui-dialog框的一部分。

The problem is:

问题是:

  1. Most dialogs are created because of clicks outside of a dialog
  2. This handler runs after those clicks have created a dialog and bubbled up to the document, so it immediately closes them.
  1. 大多数对话框是由于在对话框外单击而创建的
  2. 这个处理程序在这些点击创建一个对话框并冒泡到文档后运行,因此它立即关闭它们。

To fix this, I had to add stopPropagation to those click handlers:

为了解决这个问题,我必须将 stopPropagation 添加到这些点击处理程序中:

moreLink.on('click', function (e) {
    listBox.dialog();
    e.stopPropagation(); //Don't trigger the outside click handler
});

回答by Melanie

This question is a bit old, but in case someone wants to close a dialog that is NOT modal when user clicks somewhere, you can use this that I took from the JQuery UI Multiselect plugin. The main advantage is that the click is not "lost" (if user wants to click on a link or a button, the action is done).

这个问题有点老了,但是如果有人想在用户单击某处时关闭一个不是模态的对话框,您可以使用我从 JQuery UI Multiselect plugin 中获取的这个。主要优点是点击不会“丢失”(如果用户想要点击链接或按钮,则操作已完成)。

$myselector.dialog({
            title: "Dialog that closes when user clicks outside",
            modal:false,
            close: function(){
                        $(document).off('mousedown.mydialog');
                    },
            open: function(event, ui) { 
                    var $dialog = $(this).dialog('widget');
                    $(document).on('mousedown.mydialog', function(e) {
                        // Close when user clicks elsewhere
                        if($dialog.dialog('isOpen') && !$.contains($myselector.dialog('widget')[0], e.target)){
                            $myselector.dialog('close');
                        }            
                    });
                }                    
            });

回答by GuruKay

You can do this without using any additional plug-in

您可以在不使用任何额外插件的情况下执行此操作

var $dialog= $(document.createElement("div")).appendTo(document.body);
    var dialogOverlay;

    $dialog.dialog({
        title: "Your title",
        modal: true,
        resizable: true,
        draggable: false,
        autoOpen: false,
        width: "auto",
        show: "fade",
        hide: "fade",
        open:function(){
            $dialog.dialog('widget').animate({
                width: "+=300", 
                left: "-=150"
            });

//get the last overlay in the dom
            $dialogOverlay = $(".ui-widget-overlay").last();
//remove any event handler bound to it.
            $dialogOverlay.unbind();
            $dialogOverlay.click(function(){
//close the dialog whenever the overlay is clicked.
                $dialog.dialog("close");
            });
        }
    });

Here $dialog is the dialog. What we are basically doing is to get the last overlay widget whenever this dialog is opened and binding a click handler to that overlay to close $dialog as anytime the overlay is clicked.

这里 $dialog 是对话框。我们基本上要做的是在打开此对话框时获取最后一个覆盖小部件,并将单击处理程序绑定到该覆盖以在单击覆盖时关闭 $dialog。

回答by Jonathan Marzullo

no need for the outside events plugin...

不需要外部事件插件...

just add an event handler to the .ui-widget-overlay div:

只需向 .ui-widget-overlay div 添加一个事件处理程序:

jQuery(document).on('click', 'body > .ui-widget-overlay', function(){
     jQuery("#ui-dialog-selector-goes-here").dialog("close");
     return false;
});

just make sure that whatever selector you used for the jQuery ui dialog, is also called to close it.. i.e. #ui-dialog-selector-goes-here

只需确保您用于 jQuery ui 对话框的任何选择器也被调用以关闭它.. 即#ui-dialog-selector-goes-here

回答by Volomike

This doesn't use jQuery UI, but does use jQuery, and may be useful for those who aren't using jQuery UI for whatever reason. Do it like so:

这不使用 jQuery UI,但确实使用了 jQuery,并且可能对那些出于某种原因不使用 jQuery UI 的人有用。这样做:

function showDialog(){
  $('#dialog').show();
  $('*').on('click',function(e){
    $('#zoomer').hide();
  });
}

$(document).ready(function(){

  showDialog();    

});

So, once I've shown a dialog, I add a click handler that only looks for the first click on anything.

所以,一旦我显示了一个对话框,我就会添加一个点击处理程序,它只查找任何东西的第一次点击。

Now, it would be nicer if I could get it to ignore clicks on anything on #dialog and its contents, but when I tried switching $('*') with $(':not("#dialog,#dialog *")'), it still detected #dialog clicks.

现在,如果我能让它忽略对#dialog 及其内容的任何点击,那就更好了,但是当我尝试将 $('*') 与 $(':not("#dialog,#dialog *") 切换时'),它仍然检测到#dialog 点击。

Anyway, I was using this purely for a photo lightbox, so it worked okay for that purpose.

无论如何,我纯粹是将它用于照片灯箱,因此它可以用于此目的。