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') तत्वों को क्लिक करने पर संकेत प्रदर्शित नहीं होगा। वे तत्व संवाद के 'बाहर' हैं।
सन्नी

यदि डायलॉग खुला है तो आप केवल बाहर क्लिक के बारे में परवाह करते हैं। इसलिए इसे खोलने के बाद ही इसे बांधें।
पीटर्सनडिट

3
मैंने घटना के आधार पर फ़िल्टरिंग के बारे में एक अन्य जगह पर पढ़ा, और उस समस्या को हल किया: group.google.com/group/jquery-ui/msg/a880d99138e1e80d
सन्नी

दस्तावेज़ में संवाद का कई बार पुन: उपयोग किया जाता है, इसलिए संवाद बंद करते समय मुझे अनबाइंड करने का एक तरीका होगा। मुझे लगता है कि फ़िल्टरिंग एक सरल उपाय है।
सन्नी

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 15

37
बहुत अच्छा। मैंने इसे सिर्फ इसलिए बदल दिया ताकि मुझे आईडी संदर्भ स्पष्ट रूप से सेट न करना पड़े:$('.ui-widget-overlay').bind('click', function () { $(this).siblings('.ui-dialog').find('.ui-dialog-content').dialog('close'); });
जेम्स मैककॉर्मैक

1
मैं यह पसंद है। क्या कोई ऐसा मामला है जहां आप इसे नहीं चाहते हैं, लेकिन फिर भी बाहर बंद होने के लिए क्लिक करना चाहते हैं? मुझे इससे कोई मतलब नहीं है (मुझे लगता है कि आप जिस मोडल के साथ बाहर / नीचे के तत्वों पर मंडराने लगते हैं)।
निक स्पेसक

3
@ नाइकस्पेस - जब यह मोडल नहीं होता है तो मैं केवल एक क्लिक से किसी क्षेत्र पर ध्यान केंद्रित कर सकता हूं, एक नया संवाद खोल सकता हूं, आदि। एक मोडल डायलॉग के साथ मुझे दो क्लिक्स का उपयोग करना होगा: एक इसे बंद करने के लिए, और दूसरा एक्शन करने के लिए।
सन् 19

1
धन्यवाद! आप jQuery live bubbling का भी लाभ उठा सकते हैं। $ ('बॉडी')। ('क्लिक', '.ui-विजेट-ओवरले', बंद);
क्वांग वान

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"); }); }
मेरिडियस

ध्यान दें कि समाधान # 2 के लिए, .is ( '। Ui-संवाद, एक') .is करने के लिए बदल किया जाना है ( 'ui-संवाद, whateverYouClickOnToOpenTheDialog।')
personne3000

@Jason अल्पविराम के कारण, मुझे लगता है कि यह पंक्ति वास्तव में कह रही है "पृष्ठ में कोई ui- संवाद, या कोई लिंक नहीं"। यदि मैं आपके उदाहरण में "डायलॉग डायलॉग" लिंक को एक <span> में बदल देता हूं, तो डायलॉग खुलने के तुरंत बाद बंद हो जाता है क्योंकि विंडो ईवेंट को अंतिम रूप दिया जाता है, यही कारण है कि मुझे लगता है कि आपको उस आइटम को बाहर करने की आवश्यकता है जिसे आप खोलने के लिए क्लिक करते हैं संवाद। मुझे समझ नहीं आ रहा है कि आपको संवाद में लिंक की आवश्यकता क्यों होगी?
personne3000

@ personne3000 - वास्तव में आप संदर्भ के बारे में सही हैं, कि चयनकर्ता दोनों को चुन रहा है। मैं यह याद करने की कोशिश कर रहा हूं कि मैंने उसे क्यों जोड़ा, क्योंकि मेरे पास एक विशिष्ट कारण होना चाहिए था कि मैं इस समय याद नहीं कर रहा हूं।
जेसन

@ जैसन कई संवादों के साथ संघर्ष से बचने के लिए आप 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");
            }
        });
    });;
});

मैं एक मोडल संवाद का उपयोग नहीं कर रहा हूँ। यहां सबसे अधिक वोटों के साथ उत्तर भी मोडल संवादों के लिए है।
सन्नी

एक ही पृष्ठ पर एक से अधिक बार एक ही संवाद का उपयोग करते समय यह जाने का एकमात्र तरीका है क्योंकि यह केवल एक बार काम करेगा यदि आप इसे खुले फ़ंक्शन में बांधते हैं। इस महान विचार के लिए धन्यवाद!
MaaaHoPe

यहाँ मेरा है:$(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" );
});

कार्रवाई में उपरोक्त कोड दिखाते हुए फ़िडल


मैं इसे देख लूंगा। धन्यवाद जेन!
सन्नी

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

यह मेरे द्वारा उपयोग किए जा रहे समाधान की तुलना में सरल लगता है। मुझे इसे आज़माना होगा।
सन्नी

यह वह उपाय है जो मैंने खुद सोचा था, लेकिन मेरा एक-लाइनर है:$('body').on('click', '.ui-widget-overlay', function () { $('#myDialog').dialog('close'); });
स्टाइल

5

यह प्रश्न थोड़ा पुराना है, लेकिन अगर कोई ऐसा संवाद बंद करना चाहता है जो उपयोगकर्ता के लिए कहीं क्लिक नहीं करता है, तो आप इसे उपयोग कर सकते हैं, जिसे मैंने JQuery UI मल्टीसेप्ट प्लगइन से लिया था । मुख्य लाभ यह है कि क्लिक "खो गया" नहीं है (यदि उपयोगकर्ता लिंक या बटन पर क्लिक करना चाहता है, तो कार्रवाई की जाती है)।

$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');ऑन-क्लिक इवेंट हैंडलर
स्टीफन हैबरल

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

यहाँ $ संवाद संवाद है। जब हम मूल रूप से अंतिम ओवरले विजेट प्राप्त करने के लिए करते हैं, जब भी यह डायलॉग खोला जाता है और उस ओवरले पर क्लिक हैंडलर को बाँध कर $ डायलन को बंद करने के लिए, जैसे ही ओवरले पर क्लिक किया जाता है।


मुझे लगता है कि यह एक संवाद के लिए अन्य समाधानों के समान है। मेरा प्रश्न गैर-मोडल संवादों के लिए था।
सन्

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-go-here


मोडल संवादों को बंद करने के कई समाधान पहले ही प्रस्तावित किए जा चुके हैं। मेरा संवाद नॉन-मोडल है, और इसलिए इसमें कोई ओवरले नहीं है।
सन्

बस आपको बॉडी टैग या डिव रैपर पर क्लिक इवेंट को बांधना है और मोडल के बजाय अपने क्लिक इवेंट ट्रिगर के रूप में उपयोग करना है।
जोनाथन मार्जुलो

हाँ। यह अनिवार्य रूप से मेरा समाधान करता है। इसे संवाद के भीतर क्लिक को भी बाहर करना होगा।
सन्नी

3

यह jQuery UI का उपयोग नहीं करता है, लेकिन jQuery का उपयोग करता है, और जो भी कारण से jQuery UI का उपयोग नहीं कर रहे हैं, उनके लिए उपयोगी हो सकता है। इसे ऐसे करें:

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

$(document).ready(function(){

  showDialog();    

});

इसलिए, एक बार जब मैंने एक संवाद दिखाया है, तो मैं एक क्लिक हैंडलर जोड़ता हूं जो केवल किसी भी चीज़ पर पहले क्लिक के लिए दिखता है।

अब, यह अच्छा होगा यदि मैं इसे #dialog और इसकी सामग्री पर किसी भी चीज़ पर क्लिक को नज़रअंदाज़ करने के लिए प्राप्त कर सकता हूँ, लेकिन जब मैंने $ ('*) को $ ("# डायलॉग, # डायलॉग") के साथ स्विच करने का प्रयास किया '), यह अभी भी #dialog क्लिकों का पता लगाया है।

वैसे भी, मैं इसे पूरी तरह से एक फोटो लाइटबॉक्स के लिए उपयोग कर रहा था, इसलिए इसने उस उद्देश्य के लिए काम किया।


2

दिए गए उदाहरण (s) आईडी '# डायलॉग' के साथ एक डायलॉग का उपयोग करते हैं, मुझे ऐसे समाधान की आवश्यकता है जो किसी भी डायलॉग को बंद कर दे:

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

सभी क्रेडिट नॉन-मोडल डायलॉग को बंद करने के लिए एक्सल क्लिक के बाहर जाता है


1

जिन लोगों में आपकी रुचि है, मैंने एक जेनेरिक प्लगइन बनाया है जो एक डायलॉग को बंद करने में सक्षम करता है जब इसके बाहर क्लिक किया जाता है चाहे वह एक मोडल या नॉन-मोड्यूलर डायलॉग हो। यह एक ही पृष्ठ पर एक या कई संवादों का समर्थन करता है।

अधिक जानकारी यहाँ: http://www.coheractio.com/blog/closing-jquery-ui-dialog-widget-when-clicking-outside

लॉरेंट


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 से $ ('। किसी भी चयनकर्ता') का उपयोग करके संवाद सामग्री ढूंढना बहुत उज्ज्वल है।

प्रयत्न

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

आप वास्तव में डायलॉग उदाहरण से ओवरले प्राप्त कर रहे हैं, चीजें इस तरह से कभी गलत नहीं होंगी।


यह एक मोडल डायलॉग के लिए है? मेरा ओपी नॉन-मोडल है, इसलिए कोई ओवरले नहीं है।
सोनी

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

            }
        });
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.