jQuery UI - Close Dialog When Clicked Outside

2019-01-02 17:39发布

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.

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 events plugin

$(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条回答
弹指情弦暗扣
2楼-- · 2019-01-02 18:04

Smart Code: I am using following code so that every thing remains clear and readable. out side body will close the dialog box.

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

function closeDialogBox() {
    $('#dialog-message').dialog('close');
}
查看更多
梦醉为红颜
3楼-- · 2019-01-02 18:06

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:

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.

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

查看更多
素衣白纱
4楼-- · 2019-01-02 18:06

With the following code, you can simulate a click on the 'close' button of the dialog (change the string 'MY_DIALOG' for the name of your own dialog)

$("div[aria-labelledby='ui-dialog-title-MY_DIALOG'] div.ui-helper-clearfix a.ui-dialog-titlebar-close")[0].click();
查看更多
谁念西风独自凉
5楼-- · 2019-01-02 18:08

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");
            }
        });
    });;
});
查看更多
笑指拈花
6楼-- · 2019-01-02 18:11

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.

查看更多
步步皆殇っ
7楼-- · 2019-01-02 18:14

no need for the outside events plugin...

just add an event handler to the .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

查看更多
登录 后发表回答