jQuery UI - закрывать диалог при нажатии снаружи - PullRequest
107 голосов
/ 31 марта 2010

У меня есть диалоговое окно 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');
    });*/
});

Если я раскомментирую последнюю часть, диалог никогда не откроется. Я предполагаю, что это потому, что тот же клик, который открывает диалоговое окно, закрывает его снова.

* +1007 *

Окончательный рабочий код
Примечание: это использует 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');
    });
});

Ответы [ 19 ]

154 голосов
/ 01 декабря 2010

Извините, что перетащил это так долго, но я использовал ниже. Есть ли недостатки? Смотрите функцию открытия ...

$("#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'); 
        }); 
    }
});
78 голосов
/ 12 июня 2012

Забудьте об использовании другого плагина:

Вот 3 способа закрыть диалоговое окно jquery UI при нажатии вне popin:

Если диалоговое окно является модальным или имеет наложение фона: http://jsfiddle.net/jasonday/6FGqN/

* +1007 *

Если диалоговое окно не является модальным Метод 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;
          }


  });
30 голосов
/ 31 марта 2010

Проверьте плагин jQuery Outside Events

Позволяет вам сделать:

$field_hint.bind('clickoutside',function(){
    $field_hint.dialog('close');
});
16 голосов
/ 24 августа 2012

Просто добавьте этот глобальный скрипт, который закрывает все модальные диалоговые окна, просто щелкая их снаружи.

$(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");
            }
        });
    });;
});
10 голосов
/ 16 июня 2010
$(".ui-widget-overlay").click (function () {
    $("#dialog-id").dialog( "close" );
});

Fiddle , показывающий приведенный выше код в действии.

8 голосов
/ 09 декабря 2011

Я должен был сделать две части. Сначала внешний обработчик кликов:

$(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
});
5 голосов
/ 12 июня 2012

Этот вопрос немного устарел, но если кто-то захочет закрыть диалоговое окно, которое НЕ является модальным, когда пользователь щелкает где-то, вы можете использовать его, который я взял из плагина JQuery UI Multiselect . Основным преимуществом является то, что щелчок не «теряется» (если пользователь хочет щелкнуть ссылку или кнопку, действие выполнено).

$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');
                        }            
                    });
                }                    
            });
5 голосов
/ 07 июня 2013

Вы можете сделать это без использования какого-либо дополнительного плагина

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 - это диалог. Что мы в основном делаем, так это получаем последний виджет наложения при каждом открытии этого диалогового окна и привязываем обработчик кликов к этому наложению, чтобы закрыть диалоговое окно $, как при каждом нажатии на оверлей.

5 голосов
/ 20 августа 2013

плагин для внешних событий не нужен ...

просто добавьте обработчик событий в div .ui-widget-overlay:

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

просто убедитесь, что любой селектор, который вы использовали для диалогового окна пользовательского интерфейса jQuery, также вызывается, чтобы закрыть его ... т.е.

3 голосов
/ 31 октября 2011

Это не использует jQuery UI, но использует jQuery и может быть полезно для тех, кто по какой-либо причине не использует jQuery UI. Сделай это так:

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

$(document).ready(function(){

  showDialog();    

});

Итак, после того, как я показал диалог, я добавляю обработчик щелчков, который ищет только первый щелчок по чему-либо.

Теперь было бы лучше, если бы я мог игнорировать нажатия на что-либо на #dialog и его содержимом, но когда я попытался переключить $ ('*') с помощью $ (': not ("# dialog, # dialog * ") '), он все еще обнаружил #dialog щелчков.

Во всяком случае, я использовал это исключительно для фото лайтбокса, так что с этой целью все работало нормально.

...