代码之家  ›  专栏  ›  技术社区  ›  Sonny

jquery用户界面-单击外部时关闭对话框

  •  105
  • Sonny  · 技术社区  · 14 年前

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

    以下是打开对话框的代码:

    $(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');
        });*/
    });
    

    如果取消最后一部分的注释,对话框将永远不会打开。我想是因为打开对话框的单击操作再次关闭了对话框。


    最终工作代码
    注意:这是使用 jQuery outside events 插件

    $(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');
        });
    });
    
    19 回复  |  直到 6 年前
        1
  •  30
  •   PetersenDidIt    14 年前

    查看 jQuery Outside Events plugin

    让您做到:

    $field_hint.bind('clickoutside',function(){
        $field_hint.dialog('close');
    });
    
        2
  •  153
  •   Lee Taylor Dejan.S    7 年前

    很抱歉拖了这么久,但我用了下面的。有什么缺点吗?查看打开函数…

    $("#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'); 
            }); 
        }
    });
    
        3
  •  76
  •   Jason    12 年前

    忘记使用其他插件:

    单击外部弹出窗口时,关闭jquery用户界面对话框的方法有三种:

    如果对话框是模式/具有背景覆盖: 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');
                })
            }
        });
    }); 
    

    如果对话框是非模态方法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');
                            }
                           }
                          );
    

    非模态对话方法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;
              }
    
    
      });
    
        4
  •  15
  •   Michele Locati    12 年前

    只需添加这个全局脚本,它只需单击退出即可关闭所有模式对话框。

    $(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");
                }
            });
        });;
    });
    
        5
  •  10
  •   jezrael    9 年前
    $(".ui-widget-overlay").click (function () {
        $("#dialog-id").dialog( "close" );
    });
    

    Fiddle 正在显示上述代码。

        6
  •  8
  •   Jerph    13 年前

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

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

    这个电话 dialog('close') 关于一般 ui-dialog-content 上课,就这样结束了 全部的 如果单击不是源自一个对话框。它也将与模式对话框一起使用,因为覆盖不是 .ui-dialog 盒子。

    问题是:

    1. 大多数对话框都是由于在对话框外部单击而创建的。
    2. 这个处理程序在那些单击创建了一个对话框并冒泡到文档之后运行,因此它会立即关闭它们。

    为了解决这个问题,我必须向那些单击处理程序添加stoppropagation:

    moreLink.on('click', function (e) {
        listBox.dialog();
        e.stopPropagation(); //Don't trigger the outside click handler
    });
    
        7
  •  5
  •   Melanie    12 年前

    这个问题有点老,但是如果有人想关闭一个对话框,当用户单击某个地方时,这个对话框不是模态的,您可以使用我从 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');
                            }            
                        });
                    }                    
                });
    
        8
  •  5
  •   GuruKay    11 年前

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

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

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

        9
  •  5
  •   Jonathan Marzullo    10 年前

    不需要外部事件插件…

    只需将事件处理程序添加到.ui小部件覆盖分区:

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

    只要确保用于jquery ui对话框的任何选择器也被调用来关闭它。即 #此处显示用户界面对话框选择器

        10
  •  3
  •   Aamir    10 年前

    这不使用jquery用户界面,但使用jquery,对于那些出于任何原因不使用jquery用户界面的用户来说,可能非常有用。这样做:

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

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

    现在,如果我可以让它忽略对对话框及其内容的任何单击,那就更好了,但是当我尝试用$(':not(dialog,dialog*“)'切换$('*')时,它仍然检测到dialog单击。

    不管怎么说,我只是把它用在一个照片灯箱上,所以它就可以正常工作了。

        11
  •  2
  •   David van der Tuijn    11 年前

    给定的示例使用一个ID为“dialog”的对话框,我需要一个关闭任何对话框的解决方案:

    $.extend($.ui.dialog.prototype.options, {
        modal: true,
        open: function(object) {
            jQuery('.ui-widget-overlay').bind('click', function() {              
                var id = jQuery(object.target).attr('id');
                jQuery('#'+id).dialog('close');
            })
        }
    });
    

    感谢我的同事Youri Arkesteijn建议使用原型。

        12
  •  1
  •   Laurent    11 年前

    对于那些你感兴趣的人,我创建了一个通用插件,它可以在单击对话框外部时关闭对话框,无论是模态对话框还是非模态对话框。它支持同一页上的一个或多个对话框。

    更多信息: http://www.coheractio.com/blog/closing-jquery-ui-dialog-widget-when-clicking-outside

    劳伦特

        13
  •  1
  •   Alejo    10 年前

    我在这里发布的一篇文章中使用了这个解决方案:

    var g_divOpenDialog = null;
    function _openDlg(l_d) {
    
      // http://stackoverflow.com/questions/2554779/jquery-ui-close-dialog-when-clicked-outside
      jQuery('body').bind(
       'click',
       function(e){
        if(
          g_divOpenDialog!=null 
          && !jQuery(e.target).is('.ui-dialog, a')
          && !jQuery(e.target).closest('.ui-dialog').length
        ){
          _closeDlg();
        }
       }
      );
    
      setTimeout(function() {
        g_divOpenDialog = l_d;
        g_divOpenDialog.dialog();
      }, 500);
    }
    function _closeDlg() {
      jQuery('body').unbind('click');
      g_divOpenDialog.dialog('close');
      g_divOpenDialog.dialog('destroy');
      g_divOpenDialog = null;
    }
    
        14
  •  1
  •   Nikola Mirković - Johnny    8 年前

    我在一页上制作预览模式时遇到了同样的问题。在大量的谷歌搜索之后,我发现了这个非常有用的解决方案。对于事件和目标,它检查单击发生的位置,并根据其触发操作或不执行任何操作。

    Code Snippet Library site

    $('#modal-background').mousedown(function(e) {
    var clicked = $(e.target);  
    if (clicked.is('#modal-content') || clicked.parents().is('#modal-content')) 
        return; 
    } else {  
     $('#modal-background').hide();
    }
    });
    
        15
  •  1
  •   Community Tales Farias    7 年前

    这是唯一适合我的非模态对话的方法

    $(document).mousedown(function(e) {
        var clicked = $(e.target); // get the element clicked
        if (clicked.is('#dlg') || clicked.parents().is('#dlg') || clicked.is('.ui-dialog-titlebar')) {
            return; // click happened within the dialog, do nothing here
        } else { // click was outside the dialog, so close it
            $('#dlg').dialog("close");
        }
    });
    

    所有学分都归车轴
    Click outside non-modal dialog to close

        16
  •  0
  •   Brandon    9 年前

    “这并不简单,事实上你不需要任何插件,只需要jquery或者用简单的javascript就可以了。

    $('#dialog').on('click', function(e){
      e.stopPropagation();
    });
    $(document.body).on('click', function(e){
      master.hide();
    });
    
        17
  •  0
  •   badboy    9 年前

    我不认为使用整个DOM中的$('.any selector')来查找对话内容是如此的明智。

    尝试

    $('<div />').dialog({
        open: function(event, ui){
            var ins = $(this).dialog('instance');
            var overlay = ins.overlay;
            overlay.off('click').on('click', {$dialog: $(this)}, function(event){
                event.data.$dialog.dialog('close');
            });
        }
    });
    

    你真的从它所属的对话框实例中得到了覆盖,事情永远不会这样出错。

        18
  •  0
  •   perkas    9 年前

    使用以下代码,您可以模拟单击对话框的“关闭”按钮。 (将字符串'my_dialog'更改为您自己的对话框名称)

    $("div[aria-labelledby='ui-dialog-title-MY_DIALOG'] div.ui-helper-clearfix a.ui-dialog-titlebar-close")[0].click();
    
        19
  •  0
  •   Farid Abbas    6 年前

    智能代码: 我使用下面的代码,这样每件事情都保持清晰可读。 外侧主体将关闭对话框。

    $(document).ready(function () {
       $('body').on('click', '.ui-widget-overlay', closeDialogBox);
    });
    
    function closeDialogBox() {
        $('#dialog-message').dialog('close');
    }