Rileva clic su elemento esterno?

Simile a questa domanda , ma facendo un passo avanti. Vorrei rilevare i clic al di fuori di un insieme di elementi, che sto gestendo nel modo seguente:

$('#menu div').live('click', function() { // Close other open menu items, if any. // Toggle the clicked menu item. $('body').one('click', function(event) { // Hide the menu item. event.stopPropagation(); }); }); 

Questo funziona come un incantesimo, sfortunatamente, quando un’altra voce di menu è aperta e si fa clic su un secondo, sono necessari due clic per aprire il secondo elemento. Il primo clic nasconde la prima voce di menu che era aperta, la seconda mostra la seconda voce di menu.

Il comportamento “corretto” funziona nel modo seguente:

  • Facendo clic su una voce di menu si apre.
  • Facendo clic sulla stessa voce di menu (o sui suoi figli) lo si chiude.
  • Facendo clic su un’altra voce di menu si chiude la prima, si apre la seconda.
  • Facendo clic fuori dalle voci di menu (aperte) le chiude.

Ho provato quanto segue al posto del suddetto $('body').one() ordine di ignorare i clic sugli elementi del menu con scarso successo:

 // Captures click on menu items in spite of the not. $('*').not('#menu *').one('click', function() { // Hide menu } $('*:not(#menu)').one('click', function() { // Hide menu } 

Come sempre, grazie per qualsiasi aiuto!

Basta spostare all’esterno il gestore del body click e fare qualcosa del genere:

 $('body').bind('click', function(e) { if($(e.target).closest('#menu').length == 0) { // click happened outside of menu, hide any visible menu items } }); 

È stato erroneamente indicato nei commenti che e.target non funziona in IE; questo non è vero in quanto l’object Event di jQuery corregge queste incoerenze laddove necessario (IE, Safari).

L’ho scritto molto tempo fa, prima dei giorni di gloria di jQuery …

 function clickedOutsideElement(elemId) { var theElem = getEventTarget(window.event); while(theElem != null) { if(theElem.id == elemId) return false; theElem = theElem.offsetParent; } return true; } function getEventTarget(evt) { var targ = (evt.target) ? evt.target : evt.srcElement; if(targ != null) { if(targ.nodeType == 3) targ = targ.parentNode; } return targ; } document.onclick = function() { if(clickedOutsideElement('divTest')) alert('Outside the element!'); else alert('Inside the element!'); }