Jquery में बंद करने के लिए बाहर के मेनू पर क्लिक करें


107

इसलिए मेरे पास एक ड्रॉप-डाउन मेनू है जो एक क्लिक पर दिखाता है, व्यावसायिक आवश्यकताओं के अनुसार। आपके द्वारा इससे दूर जाने के बाद मेनू फिर से छिप जाता है।

लेकिन अब मुझे यह पूछा जा रहा है कि जब तक उपयोगकर्ता दस्तावेज़ पर कहीं भी क्लिक नहीं करता है, तब तक यह बना रहेगा। इसे किस तरह पूर्ण कर सकते है?

यह एक सरलीकृत संस्करण है जो मेरे पास अभी है:

$(document).ready(function() {
  $("ul.opMenu li").click(function(){
   $('#MainOptSubMenu',this).css('visibility', 'visible');
  });

  $("ul.opMenu li").mouseleave(function(){
      $('#MainOptSubMenu',this).css('visibility', 'hidden');
  });
});



<ul  class="opMenu">
  <li id="footwo" class="">
    <span id="optImg" style="display: inline-block;"> <img src="http://localhost.vmsinfo.com:8002/insight/images/options-hover2.gif"/> </span>
      <ul id="MainOptSubMenu" style="visibility: hidden; top: 25px; border-top: 0px solid rgb(217, 228, 250); background-color: rgb(217, 228, 250); padding-bottom: 15px;">
        <li>some</li>
       <li>nav</li>
       <li>links</li>
       </ul>
    </li>
</ul> 

मैं इस $('document[id!=MainOptSubMenu]').click(function()सोच की तरह कुछ की कोशिश की यह मेनू है कि कुछ भी पर ट्रिगर होगा, लेकिन यह काम नहीं किया।



जवाबों:


196

उपयोग किए गए इस प्रश्न पर एक नज़र डालें:

मैं एक तत्व के बाहर एक क्लिक का पता कैसे लगा सकता हूं?

विंडो को बंद करने वाले दस्तावेज़ निकाय पर एक क्लिक ईवेंट संलग्न करें। विंडो में एक अलग क्लिक ईवेंट संलग्न करें जो दस्तावेज़ निकाय के प्रसार को रोकता है।
$('html').click(function() {
  //Hide the menus if visible
});

$('#menucontainer').click(function(event){
    event.stopPropagation();
});


16
इसकी बहुत ही सुंदर लेकिन आपको $ ('html') का उपयोग करना चाहिए। क्लिक करें () शरीर नहीं। शरीर में हमेशा अपनी सामग्री की ऊंचाई होती है। इसमें बहुत अधिक सामग्री नहीं है या स्क्रीन बहुत अधिक है, यह केवल शरीर द्वारा भरे गए हिस्से पर काम करता है। से कॉपी करें: stackoverflow.com/questions/152975/… - meo 25 फरवरी को 15:35
बजे

महान समाधान। किसी भी विचार क्यों यह .click () के साथ काम करता है और .live ('क्लिक करें', 'func ...' के साथ नहीं?
Hat

3
इस दृष्टिकोण के साथ एकमात्र समस्या यह है कि जिन वस्तुओं में पहले से ही एक क्लिक श्रोता है, जो अन्य कारणों से रोकें, कोई प्रभाव नहीं पड़ता है। मैं समझता हूं कि ऐसा क्यों है, लेकिन यह अभी भी इस समाधान की एक सीमा है।
दानह

53

उत्तर सही है, लेकिन यह एक श्रोता को जोड़ देगा जो आपके पृष्ठ पर एक क्लिक होने पर हर बार चालू हो जाएगा। उससे बचने के लिए, आप श्रोता को केवल एक समय के लिए जोड़ सकते हैं:

$('a#menu-link').on('click', function(e) {
    e.preventDefault();
    e.stopPropagation();

    $('#menu').toggleClass('open');

    $(document).one('click', function closeMenu (e){
        if($('#menu').has(e.target).length === 0){
            $('#menu').removeClass('open');
        } else {
            $(document).one('click', closeMenu);
        }
    });
});

संपादित करें: यदि आप stopPropagation()प्रारंभिक बटन पर बचना चाहते हैं तो आप इसका उपयोग कर सकते हैं

var $menu = $('#menu');

$('a#menu-link').on('click', function(e) {
    e.preventDefault();

    if (!$menu.hasClass('active')) {
        $menu.addClass('active');

        $(document).one('click', function closeTooltip(e) {
            if ($menu.has(e.target).length === 0 && $('a#menu-link').has(e.target).length === 0) {
                $menu.removeClass('active');
            } else if ($menu.hasClass('active')) {
                $(document).one('click', closeTooltip);
            }
        });
    } else {
        $menu.removeClass('active');
    }
});

मैं इस कोड को बहुत देखता हूं, क्या यह हर बार मेनू लिंक पर क्लिक करने पर दस्तावेज़ में एक नया क्लिक फ़ंक्शन नहीं जोड़ेगा? इसलिए यदि आप पृष्ठ को रीफ्रेश किए बिना 1000 बार मेनू लिंक पर क्लिक करते हैं, तो आपके पास 1000 कार्य मेमोरी लेने और निष्पादन भी होगा?
22:13

कोई बात नहीं, मैंने "एक" फ़ंक्शन नहीं देखा, अब मुझे समझ में आया कि यह क्यों काम करता है: api.jquery.com/one
eselk

2
अच्छा समाधान लेकिन मुझे हैंडलर e.stopPropagation()में फायरिंग से पहली घटना को रोकने के लिए क्रोम में उपयोग करना पड़ाone()
antfx

18

stopPropagationविकल्पों बुरा है क्योंकि वे अन्य मेनू कि HTML तत्व के पास संचालकों संलग्न हो सकता है सहित अन्य ईवेंट हैंडलर्स साथ हस्तक्षेप कर सकते हैं।

यहाँ user2989143 के उत्तर पर आधारित एक सरल समाधान है :

$('html').click(function(event) {
    if ($(event.target).closest('#menu-container, #menu-activator').length === 0) {
        $('#menu-container').hide();
    }
});

17

यदि आपके मामले में एक प्लगइन का उपयोग करना ठीक है, तो मैं सुझाव देता हूं कि बेन अल्मन के क्लिकआउटसाइड प्लगइन यहां स्थित है :

इसका उपयोग इस प्रकार सरल है:

$('#menu').bind('clickoutside', function (event) {
    $(this).hide();
});

उम्मीद है की यह मदद करेगा।


8

2 विकल्प जो आप जांच सकते हैं:

  • मेनू दिखाने पर, शेष पेज को कवर करने के पीछे एक बड़ा खाली DIV रखें और मेनू (और स्वयं) को बंद करने के लिए एक ऑन-क्लिक इवेंट दें। यह लाइटबॉक्स के साथ उपयोग की जाने वाली विधियों के समान है जहां पृष्ठभूमि पर क्लिक करने से लाइटबॉक्स बंद हो जाता है
  • मेनू दिखाने पर, मेन्यू बंद करने वाले निकाय पर एक बार क्लिक करने वाले ईवेंट हैंडलर को संलग्न करें। आप इसके लिए jQuery के '.one ()' का उपयोग करें।

6

मुझे ग्रिस्मो के समाधान का एक संस्करण मिला और डेनिस के समाधान ने मेरे मुद्दे को ठीक कर दिया।

$(".MainNavContainer").click(function (event) {
    //event.preventDefault();  // Might cause problems depending on implementation
    event.stopPropagation();

    $(document).one('click', function (e) {
        if(!$(e.target).is('.MainNavContainer')) {
            // code to hide menus
        }
    });
});

5

मैं एक ही पृष्ठ में एक ही व्यवहार के साथ कई तत्वों के साथ इस समाधान का उपयोग करता हूं:

$("html").click(function(event){
    var otarget = $(event.target);
    if (!otarget.parents('#id_of element').length && otarget.attr('id')!="id_of element" && !otarget.parents('#id_of_activator').length) {
        $('#id_of element').hide();
    }
});

stopPropagation () एक बुरा विचार है, यह बटन और लिंक सहित कई चीजों के मानक व्यवहार को तोड़ता है।


यह बहुत अच्छा है, लेकिन आप इसे सरल बना सकते हैं$target.closest('#menu-container, #menu-activator').length === 0
कोड कमांडर

5

मैंने हाल ही में इसी मुद्दे का सामना किया है। मैंने निम्नलिखित कोड लिखा है:

    $('html').click(function(e) {
      var a = e.target;
      if ($(a).parents('.menu_container').length === 0) {
        $('.ofSubLevelLinks').removeClass('active'); //hide menu item
        $('.menu_container li > img').hide(); //hide dropdown image, if any
     }
    });

इसने मेरे लिए पूरी तरह से काम किया है।


4

इस बारे में क्या?

    $(this).mouseleave(function(){  
        var thisUI = $(this);
        $('html').click(function(){
                thisUI.hide();
            $('html').unbind('click');
         });
     });

3

मुझे क्लिक-ईवेंट के बजाय मूसडाउन-ईवेंट का उपयोग करना अधिक उपयोगी लगता है। यदि उपयोगकर्ता क्लिक-ईवेंट के साथ पृष्ठ पर अन्य तत्वों पर क्लिक करता है, तो क्लिक-ईवेंट काम नहीं करता है। JQuery के एक () विधि के साथ संयोजन में यह इस तरह दिखता है:

$("ul.opMenu li").click(function(event){

   //event.stopPropagation(); not required any more
   $('#MainOptSubMenu').show();

   // add one mousedown event to html
   $('html').one('mousedown', function(){
       $('#MainOptSubMenu').hide();
   });
});

// mousedown must not be triggered inside menu
$("ul.opMenu li").bind('mousedown', function(evt){
    evt.stopPropagation();
});

3

यहां तक ​​कि मैं एक ही स्थिति में आया था और मेरे एक संरक्षक ने इस विचार को खुद पर डाल दिया।

चरण: 1 जब बटन पर क्लिक किया जाता है जिस पर हमें ड्रॉप डाउन मेनू दिखाना चाहिए। फिर नीचे दिखाए गए वर्तमान पृष्ठ पर निम्न वर्ग का नाम "more_wrap_background" जोड़ें

$('.ui-page-active').append("<div class='more_wrap_background' id='more-wrap-bg'> </div>");

स्टेप -2 इसके बाद div टैग के लिए क्लिक जोड़ें

$(document).on('click', '#more-wrap-bg', hideDropDown);

जहां HideDropDown ड्रॉप डाउन मेनू को छिपाने के लिए कहा जाने वाला फ़ंक्शन है

स्टेप -3 और ड्रॉप-डाउन मेनू को छिपाते समय महत्वपूर्ण कदम यह है कि उस क्लास को हटा दें जिसे आपने पहले जोड़ा था

$('#more-wrap-bg').remove();

मैं उपरोक्त कोड में इसकी आईडी का उपयोग करके हटा रहा हूं

.more_wrap_background {
  top: 0;
  padding: 0;
  margin: 0;
  background: rgba(0, 0, 0, 0.1);
  position: fixed;
  display: block;
  width: 100% !important;
  z-index: 999;//should be one less than the drop down menu's z-index
  height: 100% !important;
}

2
$("html").click( onOutsideClick );
onOutsideClick = function( e )
{
    var t = $( e.target );
    if ( !(
        t.is("#mymenu" ) ||     //Where #mymenu - is a div container of your menu
        t.parents( "#mymenu" ).length > 0
        )   )
    {
        //TODO: hide your menu
    }
};

और श्रोता को सेट करने के लिए बेहतर है जब आपका मेनू दिखाई दे रहा हो और मेनू के छिपे होने के बाद हमेशा श्रोता को हटा दें।


1

मुझे लगता है कि आपको कुछ इस तरह की आवश्यकता है: http://jsfiddle.net/BeenYoung/BXaqW/3/

$(document).ready(function() {
  $("ul.opMenu li").each(function(){
      $(this).click(function(){
            if($(this).hasClass('opened')==false){          
                $('.opMenu').find('.opened').removeClass('opened').find('ul').slideUp();
                $(this).addClass('opened'); 
                $(this).find("ul").slideDown();
            }else{
                $(this).removeClass('opened'); 
                $(this).find("ul").slideUp();               
            }
      });
  });    
});

मुझे आशा है कि यह आपके लिए उपयोगी है!


1

': दृश्यमान' चयनकर्ता का उपयोग करें। जहां .menuitem को छिपाने वाला तत्व है ...

$('body').click(function(){
  $('.menuitem:visible').hide('fast');
});

या यदि आपके पास पहले से ही एक संस्करण में .menuitem तत्व (s) हैं ...

var menitems = $('.menuitem');
$('body').click(function(){
  menuitems.filter(':visible').hide('fast');
});

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