2009-07-21 17 views
12

Ähnlich wie this question, aber einen Schritt weiter. Ich mag Klicks außerhalb eines Satzes von Gegenständen erkennen, die ich in der folgenden Art und Weise am Umgang:Erkundige Klick-Element?

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

Dies wirkt wie ein Zauber, leider, wenn ein anderer Menüpunkt geöffnet und ein zweiten geklickt wird, es erfordert zwei Klicks, um den zweiten Gegenstand zu öffnen. Der erste Klick verbirgt den ersten geöffneten Menüpunkt, der zweite zeigt das zweite Menü item.

Die „richtige“ Verhalten funktioniert auf folgende Weise:

  • Durch Klicken auf ein Menüpunkt öffnet.
  • Wenn Sie auf denselben Menüpunkt klicken (oder auf die untergeordneten Elemente), wird er geschlossen.
  • Anklicken eines anderen Menüpunktes schließt den ersten, öffnet den zweiten.
  • Wenn Sie von (geöffneten) Menüelementen wegklicken, werden sie geschlossen.

Ich habe folgend anstelle des oben $('body').one() ausprobiert, um Klicks auf Menüpunkte mit wenig Erfolg zu ignorieren:

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

Wie immer, vielen Dank für jede Hilfe!

Antwort

29

Bewegen Sie einfach den Körper Click-Handler außerhalb und etwas tun, wie folgt aus:

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

Es wurde fälschlicherweise in den Kommentaren darauf hingewiesen, dass e.target in IE nicht funktioniert; dies ist nicht wahr, da jQuery's Event object diese Inkonsistenzen bei Bedarf behebt (IE, Safari).

+0

Was ist der Zweck des 'bewegten Handler außerhalb des Menüs klicken Handler body' klicken? Es scheint die gleiche Aufgabe zu erfüllen (ohne den Overhead, jeden Körperklick zu erfassen, wenn das Menü nie geöffnet wird), indem es angewendet wird, nachdem ein Menüelement geöffnet wurde. Oder fehlt mir etwas? – chuckg

+0

Es ist ein fairer Punkt; Ich betrachte den Overhead des Bindens und Aufhebens eines Ereignisses, wenn ein Benutzer auf einen Menüeintrag unnötig klickt. Normalerweise wird nicht viel auf eine Seite geklickt, abgesehen von einer anderen Seite. In diesem Fall ist der zusätzliche Klick-Handler völlig irrelevant. Am Ende des Tages sind beide in Ordnung, abhängig von Ihren Bedürfnissen, so dass Sie sich an den einen Handler halten können, wenn er Ihren Bedürfnissen entspricht. –

+0

e.target funktioniert nicht mit IE ... –

15

Ich schrieb dies vor langer Zeit, vor den glorreichen Tagen von 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!'); 
} 
+0

jQuery korrigiert e.target, um cross browser zu sein, was all das unnötig macht. :) –

+0

All dies ist moot, wenn Sie nur IE9 + unterstützen, ist es jetzt http://msdn.microsoft.com/en-us/library/ie/ff974946%28v=vs.85%29.aspx behoben – Gabe

Verwandte Themen