jQuery UI-외부 클릭시 대화 상자 닫기


113

특정 요소를 클릭하면 표시되는 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 플러그인을 사용하고 있습니다.

$(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 외부 이벤트가 플러그인

다음을 수행 할 수 있습니다.

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

$ ( '. hint') 요소를 클릭 할 때 힌트가 표시되지 않는다는 점에서 동일한 동작이 발생합니다. 이러한 요소는 대화 상자 '외부'입니다.
Sonny

대화 상자가 열려있는 경우 외부 클릭에만 관심이 있습니다. 따라서 개봉 한 후에 만 ​​묶으십시오.
PetersenDidIt

3
이벤트를 기반으로 한 필터링에 대해 다른 곳에서 읽었고 그로
Sonny

대화 상자는 문서에서 여러 번 재사용되므로 대화 상자를 닫을 때 바인딩을 해제하는 방법이 필요했습니다. 필터링이 더 간단한 솔루션이라고 생각합니다.
Sonny

159

오랜만에 끌어서 미안하지만 아래를 사용했습니다. 단점이 있습니까? 열기 기능보기 ...

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

1
난이게 좋아. 모달을 원하지 않지만 외부를 클릭하여 닫고 싶은 경우가 있습니까? 나에게 의미가 없습니다 (모달을 사용하면 요소 외부 / 아래에서 마우스를 잃을 것 같습니다).
Nick Spacek

3
@NickSpacek-모달이 아닐 때 한 번의 클릭으로 필드에 포커스를 설정하고 새 대화 상자를 열 수 있습니다. 모달 대화 상자를 사용하려면 두 번의 클릭을 사용해야합니다. 하나는 닫고 다른 하나는 다음 작업을 수행합니다.
Sonny

1
감사! jQuery 라이브 버블 링을 활용할 수도 있습니다. $ ( 'body'). on ( 'click', '.ui-widget-overlay', close);
Quang Van

78

다른 플러그인을 사용하지 마십시오.

popin 외부를 클릭 할 때 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"); }); }
meridius 2013 년

솔루션 # 2의 경우 .is ( '. ui-dialog, a')를 .is ( '. ui-dialog, whateverYouClickOnToOpenTheDialog')로 변경해야합니다.
personne3000

@Jason 쉼표 때문에이 줄은 실제로 "ui-dialog 또는 페이지의 링크가 아닙니다"라고 말합니다. 예에서 "대화 열기"링크를 <span>으로 변경하면 창 이벤트가 마지막으로 트리거되기 때문에 대화 상자가 열린 직후 닫힙니다. 따라서 클릭 한 항목을 제외해야합니다. 대화. 대화 상자에서 링크를 참조해야하는 이유를 이해할 수 없습니다.
personne3000

@ personne3000-실제로 선택자가 둘 다 선택하는 컨텍스트에 대해 맞습니다. 나는 그 순간에 내가 기억하지 못하는 특별한 이유가 있었음에 틀림없이 내가 그것을 추가 한 이유를 기억하려고 노력하고있다.
Jason

여러 대화 상자와 피할 충돌에 @ 제이슨 당신은 이벤트를 네임 스페이스 사용할 수 있습니다click.myNamespace
크리스토프 후씨

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 함수에서 바인딩하면 한 번만 작동하므로 이것이 유일한 방법입니다. 이 훌륭한 아이디어에 감사드립니다!
MaDaHoPe

여기 내 것 :$(document).on('click', '.ui-widget-overlay', function() { $('#'+$('.ui-dialog-content')[0].id).dialog('close'); });
mr5 dec.

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

위의 코드가 작동하는 것을 보여주는 바이올린 .


제가 살펴 볼게요. 감사합니다 Jen!
Sonny

8

나는 두 부분을해야했다. 먼저 외부 클릭 핸들러 :

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

이것은 내가 사용하는 솔루션보다 간단하게 들립니다. 나는 그것을 시도해야 할 것입니다.
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 2014

1
@Melanie, 귀하의 솔루션이 다른 것보다 더 적용 가능하다고 생각합니다. 한 사람을위한 플러그인 생성 '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 대화 상자에 사용했던 선택기가 닫히도록 호출되었는지 확인하십시오. ie # ui-dialog-selector-goes-here


모달 대화 상자를 닫기위한 몇 가지 솔루션이 이미 제안되었습니다. 내 대화 상자는 모달이 아니므로 오버레이가 없습니다.
Sonny

단순히 클릭 이벤트를 body 태그 또는 div 래퍼에 바인딩하고 모달 대신 클릭 이벤트 트리거로 사용하는 것보다.
조나단 Marzullo

예. 그것이 본질적으로 내 솔루션이하는 일입니다. 또한 대화 상자 내에서 클릭을 제외해야합니다.
Sonny

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'인 하나의 대화 상자를 사용하며 대화 상자를 닫는 솔루션이 필요했습니다.

$.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

이것은 NON-MODAL 대화 상자에서 나를 위해 일한 유일한 방법입니다.

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

모든 크레딧은 Axle로 이동
합니다. 닫으려면 비 모달 대화 상자 외부를 클릭하십시오.



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

한 페이지에서 미리보기 모달을 만드는 동안 동일한 문제가 발생했습니다. 인터넷 검색을 많이 한 후에 매우 유용한 솔루션을 찾았습니다. 이벤트 및 대상을 사용하여 클릭이 발생한 위치를 확인하고 이에 따라 작업을 트리거하거나 아무것도 수행하지 않습니다.

코드 조각 라이브러리 사이트

$('#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

İt는 간단합니다. 실제로 플러그인이 필요하지 않습니다. jquery 만 있거나 간단한 자바 스크립트로 할 수 있습니다.

$('#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.