jQuery UI-外部をクリックしたときにダイアログを閉じる


113

特定の要素をクリックすると表示されるjQuery UI 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');
    });*/
});

最後の部分のコメントを外すと、ダイアログが開きません。ダイアログを開くのと同じクリックが再び閉じているためだと思います。


最終的な作業コード
注:これは、イベントプラグイン外部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');
    });
});

回答:


31

jQuery Outside Eventsプラグインをチェックしてください

あなたがすることができます:

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

$( '。hint')要素をクリックしてもヒントが表示されないという点で、同じ動作をしています。これらの要素はダイアログの「外側」にあります。
Sonny

ダイアログが開いている場合は、外側をクリックするだけです。したがって、開いた後にのみバインドしてください。
PetersenDidIt

3
イベントに基づくフィルタリングについて別の場所を読み、問題を解決しました:groups.google.com/group/jquery-ui/msg/a880d99138e1e80d
Sonny

ダイアログはドキュメント内で何度も再利用されるため、ダイアログを閉じるときにバインドを解除する方法が必要になります。フィルタリングはもっと簡単な解決策だと思います。
Sonny

159

長い間これを上にドラッグして申し訳ありませんが、以下を使用しました。欠点はありますか?open関数を参照してください...

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

18
実際、これはUIウィンドウがモーダルの場合にのみ機能します。モーダルダイアログを閉じたい場合に便利です
stumac85

37
非常に素晴らしい。:私は明示的にIDの参照を設定する必要はありませんでしたので、私はちょうどこれにそれを変更$('.ui-widget-overlay').bind('click', function () { $(this).siblings('.ui-dialog').find('.ui-dialog-content').dialog('close'); });
ジェームズ・マコーマック

1
私はこれが好きです。モーダルにしたくないが、外側をクリックして閉じたい場合はありますか?私には意味がありません(モーダルでは、要素の外側/下でホバリングを失うと思います)。
Nick Spacek 2012年

3
@NickSpacek-モーダルではない場合、フィールドにフォーカスを設定したり、新しいダイアログを開いたりすることができます。モーダルダイアログでは、2つのクリックを使用する必要があります。1つはダイアログを閉じ、もう1つは次のアクションを実行します。
Sonny

1
ありがとう!jQueryライブバブリングを利用することもできます。$( 'body')。on( 'click'、 '.ui-widget-overlay'、close);
Quang Van

78

別のプラグインの使用を忘れます:

以下は、ポップインの外側をクリックしたときにjquery UIダイアログを閉じる3つの方法です。

ダイアログがモーダルの場合/背景オーバーレイがある場合: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;
          }


  });

2
すごい!モーダルダイアログのオープンオプション関数を少し変更したので、要素に明示的に名前を付ける必要はありません。open : function () { $('.ui-widget-overlay').on('click', function () { $(this).parents("body").find(".ui-dialog-content").dialog("close"); }); }
メリディアス2013年

ソリューション#2では、.is( '。ui-dialog、a')を.is( '。ui-dialog、whateverYouClickOnToOpenTheDialog')に変更する必要があることに注意してください
personne3000

@Jasonはコンマのため、この行は実際には「ui-dialogまたはページ内のリンクではない」と言っていると思います。例の[ダイアログを開く]リンクを<span>に変更すると、ウィンドウイベントが最後にトリガーされるため、開いた直後にダイアログが閉じます。そのため、クリックして開いたアイテムを除外する必要があると思いますダイアログ。ダイアログでリンクを参照する必要がある理由がわかりません。
personne3000

@ personne3000-実際には、セレクターが両方を選択しているというコンテキストについて正しいです。現時点では覚えていない特定の理由があったので、なぜそれを追加したのかを思い出そうとしています。
Jason

@Jasonは、複数のダイアログとの競合を回避するために、名前空間付きイベントを使用できますclick.myNamespace
Christophe Roussy 14年

17

このグローバルスクリプトを追加するだけで、すべてのモーダルダイアログが閉じられます。

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

モーダルダイアログを使用していません。ここで最も賛成票が多い答えは、モーダルダイアログにも当てはまります。
Sonny

同じページで同じダイアログを複数回使用する場合、open関数でバインドすると1回しか機能しないため、これが唯一の方法です。この素晴らしいアイデアをありがとう!
MaDaHoPe

:ここでの鉱山だ$(document).on('click', '.ui-widget-overlay', function() { $('#'+$('.ui-dialog-content')[0].id).dialog('close'); });
MR5

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

上記のコードの動作を示すフィドル


見てみましょう。ジェンさん、ありがとう!
Sonny

8

私は2つの部分をしなければなりませんでした。最初に外側のクリックハンドラー:

$(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クラスを呼び出すため、クリックが1つのダイアログで発生しなかった場合、すべてのダイアログが閉じます。オーバーレイは.ui-dialogボックスの一部ではないため、モーダルダイアログでも機能します。

問題は:

  1. ほとんどのダイアログは、ダイアログ外のクリックが原因で作成されます
  2. このハンドラーは、それらのクリックがダイアログを作成し、ドキュメントにバブリングした後に実行されるため、すぐに閉じます。

これを修正するには、これらのクリックハンドラーにstopPropagationを追加する必要がありました。

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

これは、私が使用しているソリューションよりも簡単に聞こえます。私はそれを試さなければならないでしょう。
Sonny

これは私が自分自身の考えソリューションですが、鉱山はワンライナーです:$('body').on('click', '.ui-widget-overlay', function () { $('#myDialog').dialog('close'); });
styfle

5

この質問は少し古いですが、誰かがどこかをクリックしたときにモーダルではないダイアログを閉じたい場合は、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');
                        }            
                    });
                }                    
            });

var $dialog = $(this).dialog('widget');オンクリックイベントハンドラー内を移動する必要がありました
Stefan Haberl

1
@メラニー、私はあなたの解決策が他のものよりも適切であると思います。1人の男があなたのアプローチに基づいて「jquiダイアログ」のプラグインを作成しました-githubのjs
resnyanskiy

5

追加のプラグインを使用せずにこれを行うことができます

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を閉じます。


これは、モーダルダイアログの他のソリューションに似ていると思います。私の質問は、非モーダルダイアログに関するものでした。
Sonny

5

外部イベントプラグインは必要ありません...

.ui-widget-overlay divにイベントハンドラーを追加するだけです。

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

jQueryのuiダイアログに使用したセレクターが、それを閉じるためにも呼び出されることを確認してください。つまり、#ui-dialog-selector-goes-here


モーダルダイアログを閉じるためのいくつかのソリューションがすでに提案されています。私のダイアログは非モーダルなので、オーバーレイがありません。
Sonny

クリックイベントをbodyタグまたはdivラッパーにバインドし、モーダルの代わりにクリックイベントトリガーとして使用するだけです。
ジョナサン

はい。それが基本的に私のソリューションです。また、ダイアログ内のクリックを除外する必要があります。
ソニー

3

これはjQuery UIを使用しませんが、jQueryを使用します。何らかの理由でjQuery UIを使用していない場合に役立ちます。そのようにしてください:

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

$(document).ready(function(){

  showDialog();    

});

したがって、ダイアログを表示したら、最初のクリックのみを探すクリックハンドラーを追加します。

#dialogとその内容のクリックを無視できるようにすると良いでしょうが、$( ':not( "#dialog、#dialog *")で$(' * ')を切り替えようとしたとき')、それでも#dialogクリックが検出されました。

とにかく、私はこれを純粋にフォトライトボックスに使用していたので、その目的には問題ありませんでした。


2

指定された例では、ID '#dialog'のダイアログを1つ使用しています。ダイアログを閉じるソリューションが必要でした。

$.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に感謝します。


2

これは私の非モーダルダイアログで私のために働いた唯一の方法です

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

すべてのクレジットは非モーダルダイアログの外側のアクスルクリックに移動し
て閉じます



1

私はここに投稿されたものに基づいてこのソリューションを使用します:

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

1

1ページでプレビューモーダルを作成するときに、同じ問題が発生しました。多くのググリングの後、私はこの非常に便利な解決策を見つけました。イベントとターゲットでは、クリックが発生した場所をチェックし、それに応じてアクションをトリガーするか、何もしません。

コードスニペットライブラリサイト

$('#modal-background').mousedown(function(e) {
var clicked = $(e.target);  
if (clicked.is('#modal-content') || clicked.parents().is('#modal-content')) 
    return; 
} else {  
 $('#modal-background').hide();
}
});

0

単純ではありませんが、実際にはプラグインは必要ありません。jqueryを使用するか、単純なJavaScriptで実行できます。

$('#dialog').on('click', function(e){
  e.stopPropagation();
});
$(document.body).on('click', function(e){
  master.hide();
});

0

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

オーバーレイが属するダイアログインスタンスからオーバーレイを実際に取得しているので、この方法で問題が発生することはありません。


これはモーダルダイアログ用ですか?私のOPは非モーダルであるため、オーバーレイはありません。
Sonny

0

次のコードを使用すると、ダイアログの「閉じる」ボタンのクリックをシミュレートできます(独自のダイアログの名前の文字列「MY_DIALOG」を変更します)

$("div[aria-labelledby='ui-dialog-title-MY_DIALOG'] div.ui-helper-clearfix a.ui-dialog-titlebar-close")[0].click();

0

スマートコード:次のコードを使用して、すべてが明確で読みやすいようにしています。外側のボディはダイアログボックスを閉じます。

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

function closeDialogBox() {
    $('#dialog-message').dialog('close');
}

0

私はこのコードを使用することになりました。このコードは、ページ上の開いているダイアログで機能し、ツールチップのクリックを無視し、閉じられているダイアログのリソースもクリーンアップします。


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

            }
        });
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.