Fare clic sul menu esterno per chiudere in jQuery

Quindi ho un menu a discesa che mostra un clic, in base ai requisiti aziendali. Il menu viene nuovamente nascosto dopo che il mouse è stato rimosso.

Ma ora mi viene chiesto di mantenerlo attivo finché l’utente non fa clic in qualsiasi punto del documento. Come può essere realizzato?

Questa è una versione semplificata di ciò che ho ora:

$(document).ready(function() { $("ul.opMenu li").click(function(){ $('#MainOptSubMenu',this).css('visibility', 'visible'); }); $("ul.opMenu li").mouseleave(function(){ $('#MainOptSubMenu',this).css('visibility', 'hidden'); }); }); 
    • some
    • nav
    • links

Ho provato qualcosa di simile a $('document[id!=MainOptSubMenu]').click(function() pensando che si innescherebbe su tutto ciò che non era il menu, ma non ha funzionato.

Dai un’occhiata all’approccio usato per questa domanda:

Come posso rilevare un clic all’esterno di un elemento?

Albind un evento click al corpo del documento che chiude la finestra. Albind un evento click separato alla finestra che interrompe la propagazione al corpo del documento.

 $('html').click(function() { //Hide the menus if visible }); $('#menucontainer').click(function(event){ event.stopPropagation(); }); 

La risposta è giusta, ma aggiungerà un listener che verrà triggersto ogni volta che si verifica un clic sulla tua pagina. Per evitare ciò, è ansible aggiungere il listener solo per una volta:

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

Modifica: se vuoi evitare stopPropagation() sul pulsante iniziale puoi usare questo

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

Se l’uso di un plugin è ok nel tuo caso, ti suggerisco di inserire il plug-in clickoutside di Ben Alman:

il suo utilizzo è semplice come questo:

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

spero che questo ti aiuti.

Le opzioni stopPropagation sono errate perché possono interferire con altri gestori di eventi, inclusi altri menu che potrebbero aver collegato gestori di chiusura all’elemento HTML.

Ecco una soluzione semplice basata sulla risposta di user2989143 :

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

2 opzioni che puoi esaminare:

  • Alla visualizzazione del menu, posiziona un DIV vuoto di grandi dimensioni dietro a coprire il resto della pagina e assegnagli un evento su clic per chiudere il menu (e se stesso). Questo è simile ai metodi usati con i lightbox in cui il clic sullo sfondo chiude la lightbox
  • Alla visualizzazione del menu, allega un gestore di eventi click-one sul corpo che chiude il menu. Usate jQuery ‘.one ()’ per questo.

Ho recentemente affrontato lo stesso problema. Ho scritto il seguente codice:

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

Ha funzionato perfettamente per me.

che dire di questo?

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

Ho trovato una variante della soluzione di Grsmto e la soluzione di Dennis ha risolto il problema.

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

Io uso questa soluzione con più elementi con lo stesso comportamento nella stessa pagina:

 $("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 () è una ctriggers idea, questo rompe il comportamento standard di molte cose, inclusi pulsanti e collegamenti.

Trovo più utile usare l’evento mousedown invece di click-event. L’evento click non funziona se l’utente fa clic su altri elementi nella pagina con eventi di clic. In combinazione con il metodo one () di jQuery, appare come questo:

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

anche io mi sono imbattuto nella stessa situazione e uno dei miei mentori ha messo questa idea a me stessa.

fase: 1 quando si fa clic sul pulsante sul quale dovremmo mostrare il menu a discesa. quindi aggiungi il nome di class sottostante “more_wrap_background” alla pagina triggers corrente come mostrato di seguito

 $('.ui-page-active').append("
");

step-2 quindi aggiungi un clic per il tag div come

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

dove hideDropDown è la funzione da chiamare per hide il menu a discesa

Step-3 e passo importante mentre nascondi il menu a tendina è quello di rimuovere quella class che hai aggiunto in precedenza

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

Sto rimuovendo usando il suo id nel codice sopra

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

E meglio impostare l’ascoltatore solo quando il tuo menu è visibile e rimuovere sempre il listener dopo che il menu è stato nascosto.

Penso che tu abbia bisogno di qualcosa del genere: 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(); } }); }); }); 

Spero sia utile per te!

Usa il selettore ‘: visible’. Dove .menuitem è l’elemento (i) da hide …

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

O se hai già gli elementi .menuitem in una var …

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