2009-07-21 16 views
12

Podobny do this question, ale o krok dalej. Chciałbym wykryć kliknięć poza zestaw elementów, które ja magazynowe w następujący sposób:Wykryj kliknięcie elementu zewnętrznego?

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

To działa jak czar, niestety, kiedy kolejna pozycja menu jest otwarte i drugi kliknięciu wymaga dwóch kliknięć, aby otworzyć drugi element. Pierwsze kliknięcie ukrywa pierwszy element menu, który był otwarty, a drugie pokazuje drugie menu pozycji .

„poprawny” zachowanie działa w następujący sposób:

  • Kliknięcie pozycji menu otwiera.
  • Kliknięcie tego samego elementu menu (lub jego elementów podrzędnych) powoduje jego zamknięcie.
  • Kliknięcie innego elementu menu zamyka pierwszy, otwiera drugi.
  • Kliknięcie z (otwartymi) elementami menu powoduje ich zamknięcie.

Próbowałem następujących w miejsce powyżej $('body').one() aby ignorować kliknięcia pozycji menu z niewielkim sukcesem:

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

Jak zawsze, dzięki za pomoc!

Odpowiedz

29

Wystarczy przesunąć obsługi body Kliknij na zewnątrz i zrobić coś takiego:

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

został nieprawidłowo wskazał w komentarzach, że e.target nie działa w IE; nie jest to prawdą, ponieważ w razie potrzeby usuwa te niespójności (IE, Safari).

+0

Jaki jest cel przesuwając kliknij 'organ do spraw obsługi poza kliknij menu obsługi? Wygląda na to, że wykonuje to samo zadanie (bez konieczności przechwytywania każdego kliknięcia, jeśli menu nigdy nie jest otwierane) przez zastosowanie go po otwarciu pozycji menu. Czy może czegoś brakuje? – chuckg

+0

To jest sprawiedliwy punkt; Uważam, że narzut związany z wiązaniem i odłączaniem zdarzenia, gdy użytkownik kliknie element menu, jest niepotrzebny. Zwykle nie ma wiele klikania na stronie poza przejściem na inną stronę, w takim przypadku dodatkowy moduł obsługi kliknięć jest zupełnie nieistotny. Na koniec dnia oba są w porządku w zależności od twoich potrzeb, więc możesz trzymać się jednego przewodnika, jeśli pasuje on do twoich potrzeb. –

+0

e.target nie działa na IE ... –

15

Napisałem to dawno temu, zanim dni chwały 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 naprawia plik e.target, aby był przeglądarką, co powoduje, że cały ten hoopla jest niepotrzebny. :) –

+0

Wszystko to jest dyskusyjne, jeśli obsługujesz tylko IE9 +, jest teraz naprawiony http://msdn.microsoft.com/en-us/library/ie/ff974946%28v=vs.85%29.aspx – Gabe

Powiązane problemy