Wie kann der Klick außerhalb des Elements bestimmt werden?

Ich habe einige HTML-Menüs, die vollständig angezeigt werden, wenn der Benutzer auf den Titel dieser Menüs klickt. Ich möchte diese Elemente ausblenden, wenn der Benutzer außerhalb des Menübereichs klickt.

Ist so etwas mit jQuery möglich?

 $("#menuscontainer").clickOutsideThisElement(function() { // Hide the menus }); 
2160
30 сент. eingestellt von Sergio del Amo 30 sep. 2008-09-30 16:17 08 um 16:17 Uhr 2008-09-30 16:17
@ 78 Antworten
  • 1
  • 2
  • 3

HINWEIS. Die Verwendung von stopEventPropagation() sollte vermieden werden, da dies den normalen Ablauf von Ereignissen im DOM stopEventPropagation() . Weitere Informationen finden Sie in diesem Artikel . Verwenden Sie stattdessen diese Methode .

Hängen Sie ein Klickereignis an den Hauptteil des Dokuments an, das das Fenster schließt. Hängen Sie ein separates Klickereignis an einen Container an, der die Verteilung im Hauptteil des Dokuments stoppt.

 $(window).click(function() { //Hide the menus if visible }); $('#menucontainer').click(function(event){ event.stopPropagation(); }); 
1671
30 сент. Die Antwort gibt Eran Galperin vom 30. September 2008-09-30 16:38 08 um 16:38 Uhr 2008-09-30 16:38

Sie können das Click- Ereignis auf document abhören und dann sicherstellen, dass der #menucontainer nicht der Vorfahr oder das Ziel des Elements .closest() mit dem Element .closest() .

Ist dies nicht der Fall, befindet sich das Element #menucontainer außerhalb des #menucontainer und kann sicher ausgeblendet werden.

 export function hideOnClickOutside(selector) { const outsideClickListener = (event) => { $target = $(event.target); if (!$target.closest(selector).length  $(selector).is(':visible')) { $(selector).hide(); removeClickListener(); } } const removeClickListener = () => { document.removeEventListener('click', outsideClickListener) } document.addEventListener('click', outsideClickListener) } 
border=0

Bearbeiten - 2018-03-11

Für diejenigen, die jQuery nicht verwenden möchten. Hier ist der obige Code in plain vanillaJS (ECMAScript6).

https://developer.mozilla.org/en-US/docs/Web/API/Element/closest. 

1212
12 июня '10 в 11:35 2010-06-12 11:35 Die Antwort wird Art 12 Juni '10 um 11:35 2010-06-12 11:35 gegeben

Wie erkennt man einen Klick außerhalb des Elements?

Der Grund, warum diese Frage so beliebt ist und so viele Antworten hat, ist, dass sie täuschend komplex ist. Nach fast acht Jahren und Dutzenden von Antworten bin ich wirklich überrascht, wie wenig Aufmerksamkeit auf die Zugänglichkeit gelegt wird.

Ich möchte diese Elemente ausblenden, wenn der Benutzer außerhalb des Menübereichs klickt.

Dies ist eine edle Sache und ein tatsächliches Problem. Der Name der Frage ist, was die meisten Antworten zu lösen scheinen, enthält einen unglücklichen roten Hering.

Hinweis: dieses Wort ist "Klick"!

Tatsächlich möchten Sie keine Klick-Handler binden.

Wenn Sie auf Handler klicken, um das Dialogfeld zu schließen, sind Sie bereits fehlgeschlagen. Der Grund dafür ist, dass nicht jeder Klickereignisse auslöst. Benutzer, die die Maus nicht verwenden, können Ihr Dialogfeld durch Drücken der Tabulatortaste verlassen (und Ihr Popup-Menü kann eine Art Dialog sein). Anschließend können sie den Inhalt des Dialogfelds nicht lesen, ohne einen click zu starten.

Lassen Sie uns die Frage neu formulieren.

Wie schließt man den Dialog, wenn der Benutzer damit fertig ist?

Das ist das Ziel. Leider müssen wir den userisfinishedwiththedialog jetzt mit dem userisfinishedwiththedialog binden, und diese Bindung ist nicht so einfach.

Wie können wir also feststellen, dass ein Benutzer den Dialog beendet hat?

focusout Ereignis

Ein guter Anfang ist zu ermitteln, ob der Fokus den Dialog verlassen hat.

Hinweis: Seien Sie vorsichtig mit der Ereignisunschärfe. Die blur wird nicht angewendet, wenn das Ereignis mit der Sprudelphase verbunden war!

jQuery focusout wird großartig sein. Wenn Sie jQuery nicht verwenden können, können Sie in der Aufnahmephase blur :

 element.addEventListener('blur', ..., true); // use capture: ^^^^ 

Darüber hinaus müssen Sie für viele Dialoge zulassen, dass der Container den Fokus erhält. Fügen Sie tabindex="-1" damit das Dialogfeld dynamisch den Fokus erhalten kann, ohne den Tabulatorfluss zu unterbrechen.

 div { display: none; } .active { display: block; } 
Example <div id="example" tabindex="-1"> Lorem ipsum <a href="http://example.com">dolor sit amet. </div> 

Wenn Sie länger als eine Minute mit dieser Demo spielen, sollten Sie schnell mit den Problemen beginnen.

Zunächst ist der Link im Dialogfeld nicht verfügbar. Wenn Sie versuchen, darauf oder auf eine Registerkarte zu klicken, wird das Dialogfeld geschlossen, bevor die Interaktion stattfindet. Dies ist auf die Tatsache zurückzuführen, dass das Fokussieren des inneren Elements ein focusout Ereignis verursacht, bevor es erneut focusin .

Das Update ist eine Statuswartesch>setImmediate(...) oder setTimeout(..., 0) für Browser ausgeführt werden, die setImmediate nicht unterstützen. Nachdem es in die Wartesch>focusin abgebrochen werden:

 $('.submenu').on({ focusout: function (e) { $(this).data('submenuTimer', setTimeout(function () { $(this).removeClass('submenu--active'); }.bind(this), 0)); }, focusin: function (e) { clearTimeout($(this).data('submenuTimer')); } }); 

 div { display: none; } .active { display: block; } 
Example <div id="example" tabindex="-1"> Lorem ipsum <a href="http://example.com">dolor sit amet. </div> 

Das zweite Problem besteht darin, dass das Dialogfeld nicht geschlossen wird, wenn Sie erneut auf den Link klicken. Dies ist darauf zurückzuführen, dass der Dialog den Fokus verliert und beim Schließen einen Auslöser auslöst. Wenn Sie auf den Link klicken, wird der Dialog geöffnet.

Wie in der vorherigen Version müssen Sie den Fokusstatus steuern. In Anbetracht dessen, dass die Statusänderung bereits in die Wartesch> Es sollte bekannt aussehen.

 $('a').on({ focusout: function () { $(this.hash).data('timer', setTimeout(function () { $(this.hash).removeClass('active'); }.bind(this), 0)); }, focusin: function () { clearTimeout($(this.hash).data('timer')); } }); 

 div { display: none; } .active { display: block; } 
Example <div id="example" tabindex="-1"> Lorem ipsum <a href="http://example.com">dolor sit amet. </div> 

Esc- Taste

Wenn Sie der Meinung sind, dass alles durch das Verwalten der Fokuszustände erledigt wird, können Sie die Benutzererfahrung weiter vereinfachen.

Dies ist oft „angenehm zu haben“, aber in der Regel geschieht dies, wenn Sie eine modale oder Popup-Datei eines beliebigen Typs haben, die sie mit der Esc-Taste schließt.

 keydown: function (e) { if (e.which === 27) { $(this).removeClass('active'); e.preventDefault(); } } 

 div { display: none; } .active { display: block; } 
Example <div id="example" tabindex="-1"> Lorem ipsum <a href="http://example.com">dolor sit amet. </div> 

Wenn Sie wissen, dass das Dialogfeld benutzerdefinierte Elemente enthält, müssen Sie das Dialogfeld nicht direkt fokussieren. Wenn Sie ein Menü erstellen, können Sie den ersten Menüpunkt fokussieren.

 click: function (e) { $(this.hash) .toggleClass('submenu--active') .find('a:first') .focus(); e.preventDefault(); } 

 .menu { list-style: none; margin: 0; padding: 0; } .menu:after { clear: both; content: ''; display: table; } .menu__item { float: left; position: relative; } .menu__link { background-color: lightblue; color: black; display: block; padding: 0.5em 1em; text-decoration: none; } .menu__link:hover, .menu__link:focus { background-color: black; color: lightblue; } .submenu { border: 1px solid black; display: none; left: 0; list-style: none; margin: 0; padding: 0; position: absolute; top: 100%; } .submenu--active { display: block; } .submenu__item { width: 150px; } .submenu__link { background-color: lightblue; color: black; display: block; padding: 0.5em 1em; text-decoration: none; } .submenu__link:hover, .submenu__link:focus { background-color: black; color: lightblue; } 
Menu 1</a> <ul class="submenu" id="menu-1" tabindex="-1"> <li class="submenu__item"><a class="submenu__link" href="http://example.com/#1">Example 1</a></li> <li class="submenu__item"><a class="submenu__link" href="http://example.com/#2">Example 2</a></li> <li class="submenu__item"><a class="submenu__link" href="http://example.com/#3">Example 3</a></li> <li class="submenu__item"><a class="submenu__link" href="http://example.com/#4">Example 4</a></li> </ul> </li> <li class="menu__item"> <a class="menu__link" href="#menu-2">Menu 2</a> <ul class="submenu" id="menu-2" tabindex="-1"> <li class="submenu__item"><a class="submenu__link" href="http://example.com/#1">Example 1</a></li> <li class="submenu__item"><a class="submenu__link" href="http://example.com/#2">Example 2</a></li> <li class="submenu__item"><a class="submenu__link" href="http://example.com/#3">Example 3</a></li> <li class="submenu__item"><a class="submenu__link" href="http://example.com/#4">Example 4</a></li> </ul> </li> </ul> lorem ipsum <a href="http://example.com/">dolor sit amet. 

WAI-ARIA-Rollen und andere Unterstützung für die Barrierefreiheit

Ich hoffe, dass diese Antwort die Grundlagen der verfügbaren Tastatur- und Mausunterstützung für diese Funktion abdeckt. Da dies jedoch bereits von erheblicher Bedeutung ist, werde ich es vermeiden, die Rollen und Attribute von WAI-ARIA zu diskutieren. Ich empfehle jedoch dringend, dass sich die Entwickler bezüglich der Details auf die Spezifikation beziehen die Rollen, die sie verwenden müssen, und alle anderen relevanten Attribute.

220
12 июля '16 в 2:29 2016-07-12 02:29 Die Antwort ist zzzzBov 12. Juli '16 um 2:29 am 2016-07-12 02:29 gegeben

Andere Lösungen hier funktionierten nicht für mich, daher musste ich Folgendes verwenden:

 if(!$(event.target).is('#foo')) { // hide menu } 
132
07 июля '09 в 2:10 2009-07-07 02:10 Die Antwort wird an Dennis am 07. Juli 09 um 2:10 2009-07-07 02:10 gegeben

Ich habe eine Anwendung, die ähnlich funktioniert wie das Eran-Beispiel, nur dass ich beim Öffnen des Menüs ein Klickereignis an den Körper anhange ... Ein bisschen wie das:

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

Weitere Informationen zur Funktion jQuery one()

122
30 сент. Antwort von Joe Lencioni 30. September 2008-09-30 21:13 08 um 21:13 Uhr 2008-09-30 21:13
 $("#menuscontainer").click(function() { $(this).focus(); }); $("#menuscontainer").blur(function(){ $(this).hide(); }); 

Funktioniert gut für mich.

36
17 нояб. Die Antwort wird von user212621 vom 17. November gegeben. 2009-11-17 09:13 09 um 09:13 2009-11-17 09:13

Nun gibt es dafür ein Plugin: externe Events ( Blogpost )

Wenn ein clickoutside (WLOG) -Handler an ein Element gebunden ist, tritt das Folgende auf:

  • einem Array, das alle Elemente mit clickoutside-Handlern enthält, wird ein Element hinzugefügt.
  • Ein ( Namespace ) Click-Handler ist an das Dokument gebunden (falls noch nicht vorhanden)
  • Bei jedem Klick im Dokument wird das Ereignis clickoutside für die Elemente in diesem Array ausgelöst, die nicht gleich sind, oder das übergeordnete Objekt des Zielklicks
  • Außerdem ist das event.target für das clickoutside-Ereignis auf das Element festgelegt, auf das der Benutzer geklickt hat (sodass Sie sogar wissen, dass der Benutzer geklickt hat, und nicht nur, dass er außerhalb geklickt hat).

Somit werden keine Ereignisse aufgrund von Ausbreitung abgebrochen, und zusätzliche Klick-Handler können mithilfe eines externen Handlers "oben" verwendet werden.

35
05 апр. Die Antwort wird von Wolfram 05 Apr gegeben 2010-04-05 13:07 '10 um 13:07 2010-04-05 13:07

Nach Recherchen habe ich drei funktionierende Lösungen gefunden (ich habe die Links zu Referenzseiten vergessen)

Erste Entscheidung

 <script> //The good thing about this solution is it doesn't stop event propagation. var clickFlag = 0; $('body').on('click', function () { if(clickFlag == 0) { console.log('hide element here');  } else { clickFlag=0; } }); $('body').on('click','#testDiv', function (event) { clickFlag = 1; console.log('showed the element');  }); </script> 

Zweite Lösung

 <script> $('body').on('click', function(e) { if($(e.target).closest('#testDiv').length == 0) {  } }); </script> 

Dritte Lösung

 <script> var specifiedElement = document.getElementById('testDiv'); document.addEventListener('click', function(event) { var isClickInside = specifiedElement.contains(event.target); if (isClickInside) { console.log('You clicked inside') } else { console.log('You clicked outside') } }); </script> 
32
02 нояб. Die Antwort wird gegeben Rameez Rami 02 Nov. 2015-11-02 11:33 '15 um 11:33 2015-11-02 11:33

Es hat großartig für mich funktioniert!

 $('html').click(function (e) { if (e.target.id == 'YOUR-DIV-ID') { //do something } else { //do something } }); 
29
04 июня '12 в 17:08 2012-06-04 17:08 Die Antwort ist gegeben srinath 04 Juni '12 um 17:08 2012-06-04 17:08

Ich glaube nicht, dass Sie das Menü wirklich schließen müssen, wenn der Benutzer darauf klickt. Sie müssen das Menü schließen, wenn der Benutzer irgendwo auf die Seite klickt. Wenn Sie auf ein Menü oder ein Außenmenü klicken, sollte es dann richtig geschlossen werden?

Ich fand keine befriedigenden Antworten und bat darum, diesen Blogpost neulich zu schreiben. Für Pedantiker gibt es einige Fehler, die Sie beachten sollten:

  • Wenn Sie während eines Klicks einen Click-Ereignishandler an das body-Element anhängen, warten Sie vor dem Schließen des Menüs unbedingt einen zweiten Klick, und lösen Sie das Ereignis. Andernfalls wird das Klickereignis, mit dem das Menü geöffnet wurde, auf dem Bildschirm des Listeners angezeigt, der das Menü schließen soll.
  • Wenn Sie event.stopPropogation () in einem Klickereignis verwenden, kann kein anderes Element auf Ihrer Seite die Funktion zum Schließen des Klickens haben.
  • Das Anhängen eines Click-Ereignishandlers an ein Body-Element ist unbegrenzt. Dies ist keine effektive Lösung.
  • Wenn Sie den Zweck des Ereignisses und seiner Eltern mit dem Ersteller des Handlers vergleichen, wird davon ausgegangen, dass Sie das Menü schließen möchten, wenn Sie darauf klicken. Wenn Sie das Ereignis wirklich schließen möchten, klicken Sie auf eine beliebige Stelle auf der Seite.
  • Durch das Abhören von Ereignissen im body-Element wird der Code anfälliger. Der Stil ist unschuldig, da er möglicherweise gebrochen wird: body { margin-left:auto; margin-right: auto; width:960px;} body { margin-left:auto; margin-right: auto; width:960px;}
24
19 мая '11 в 0:15 2011-05-19 00:15 Die Antwort ist 34m0 19. Mai '11 um 0:15 2011-05-19 00:15

Als weiteres Poster wird gesagt, dass es viele Fehler gibt, insbesondere wenn das Element, das Sie anzeigen (in diesem Fall das Menü), interaktive Elemente enthält. Ich fand die folgende Methode ziemlich zuverlässig:

 $('#menuscontainer').click(function(event) { //your code that shows the menus fully //now set up an event listener so that clicking anywhere outside will close the menu $('html').click(function(event) { //check up the tree of the click target to check whether user has clicked outside of menu if ($(event.target).parents('#menuscontainer').length==0) { // your code to hide menu //this event listener has done its job so we can unbind it. $(this).unbind(event); } }) }); 
23
22 дек. Antwort von Benb am 22. Dezember 2011-12-22 14:59 '11 am 14:59 22.12.2011 14:59

Eine einfache Lösung für die Situation ist:

 $(document).mouseup(function (e) { var container = $("YOUR SELECTOR"); // Give you class or ID if (!container.is(e.target)  // If the target of the click is not the desired div or section container.has(e.target).length === 0) // ... nor a descendant-child of the container { container.hide(); } }); 

Das obige Skript blendet das div wenn das div click-Ereignis außerhalb des div ausgelöst wird.

Weitere Informationen finden Sie im folgenden Blog: http://www.codecanal.com/detect-click-outside-div-using-javascript/

20
15 дек. Die Antwort wird am 15. Dezember von Jitendra Damor gegeben . 2015-12-15 06:50 '15 um 6:50 2015-12-15 06:50

Überprüfen Sie den Zielpunkt des Fensterklickereignisses (es sollte im Fenster verteilt werden, wenn es nirgendwo erfasst wurde), und stellen Sie sicher, dass es sich nicht um eines der Menüelemente handelt. Wenn nicht, sind Sie nicht in Ihrem Menü.

Oder überprüfen Sie die Klickposition und prüfen Sie, ob sie sich im Menübereich befindet.

18
30 сент. Antwort von Chris MacDonald am 30. September 2008-09-30 16:20 08 um 16:20 Uhr 2008-09-30 16:20

Lösung1

Anstatt event.stopPropagation () zu verwenden, was einige Nebenwirkungen haben kann, definieren Sie einfach eine einfache Flag-Variable und fügen Sie eine if Bedingung hinzu. Ich habe es getestet und funktionierte ohne Nebenwirkungen von stopPropagation:

 var flag = "1"; $('#menucontainer').click(function(event){ flag = "0"; // flag 0 means click happened in the area where we should not do any action }); $('html').click(function() { if(flag != "0"){ // Hide the menus if visible } else { flag = "1"; } }); 

Lösung2

Verwenden Sie eine einfache if Bedingung:

 $(document).on('click', function(event){ var container = $("#menucontainer"); if (!container.is(event.target)  // If the target of the click isn't the container... container.has(event.target).length === 0) // ... nor a descendant of the container { // Do whatever you want to do when click is outside the element } }); 
18
28 янв. Antworten Iman Sedighi 28. Januar 2015-01-28 20:24 '15 um 20:24 2015-01-28 20:24

Ich hatte Erfolg mit so etwas:

 var $menuscontainer = ...; $('#trigger').click(function() { $menuscontainer.show(); $('body').click(function(event) { var $target = $(event.target); if ($target.parents('#menuscontainer').length == 0) { $menuscontainer.hide(); } }); }); 

Die Logik ist wie folgt: Wenn #menuscontainer angezeigt wird, #menuscontainer den Click-Handler an einen Körper, der #menuscontainer nur verbirgt, wenn das Ziel (click) kein Kind ist.

15
02 дек. Die Antwort wird von Chu Yeow 02 Dez. gegeben. 2010-12-02 12:53 '10 um 12:53 2010-12-02 12:53

Als Option:

 var $menu = $('#menucontainer'); $(document).on('click', function (e) { // If element is opened and click target is outside it, hide it if ($menu.is(':visible')  !$menu.is(e.target)  !$menu.has(e.target).length) { $menu.hide(); } }); 

Es ist problemlos möglich , die Verteilung von Ereignissen zu stoppen, und mehrere Menüs werden auf derselben Seite verwaltet. Wenn Sie beim ersten Öffnen des zweiten Menüs auf das zweite Menü klicken, wird die erste Erkennung in der stopPropagation-Lösung belassen.

14
24 июля '14 в 12:41 2014-07-24 12:41 Die Antwort wird von Bohdan Lyzanets am 24. Juli 14 um 12:41 Uhr 2014-07-24 12:41 gegeben

Ich habe diese Methode in einem jQuery-Kalender-Plugin gefunden.

 function ClickOutsideCheck(e) { var el = e.target; var popup = $('.popup:visible')[0]; if (popup==undefined) return true; while (true){ if (el == popup ) { return true; } else if (el == document) { $(".popup").hide(); return false; } else { el = $(el).parent()[0]; } } }; $(document).bind('mousedown.popup', ClickOutsideCheck); 
12
28 июля '11 в 17:06 2011-07-28 17:06 Die Antwort wird von Nazar Kuliyev 28. Juli 11 um 17:06 2011-07-28 17:06 gegeben

Hier ist die Lösung für Vanilla-Javascript für zukünftige Zuschauer.

Wenn Sie auf ein Element innerhalb des Dokuments klicken und auf die Elementkennung geklickt wird oder das ausgeblendete Element nicht ausgeblendet ist und das ausgeblendete Element kein Element mit einem Klick enthält, wechseln Sie das Element.

 (function () { "use strict"; var hidden = document.getElementById('hidden'); document.addEventListener('click', function (e) { if (e.target.id == 'toggle' || (hidden.style.display != 'none'  !hidden.contains(e.target))) hidden.style.display = hidden.style.display == 'none' ? 'block' : 'none'; }, false); })(); 

Wenn Sie mehrere Schalter auf derselben Seite haben, können Sie Folgendes verwenden:

  • Fügen Sie den hidden Klassennamen zum Faltelement hinzu.
  • Wenn Sie auf ein Dokument klicken, schließen Sie alle ausgeblendeten Elemente, die kein Element enthalten, mit einem Klick und werden nicht ausgeblendet.
  • Wenn das angeklickte Element ein Schalter ist, wechseln Sie das angegebene Element.

10
20 мая '15 в 1:52 2015-05-20 01:52 Die Antwort wird Tiny Giant am 20. Mai 15 um 01:52 2015-05-20 01:52 gegeben

Ein Ereignis verfügt über eine Eigenschaft namens event.path des Elements, bei der es sich um eine "statisch geordnete Liste aller Vorfahren in Baumstruktur" handelt. Um zu prüfen, ob ein Ereignis in einem bestimmten DOM-Element oder einem seiner untergeordneten Elemente aufgetreten ist, prüfen Sie einfach den Pfad zu diesem bestimmten DOM-Element. Es kann auch verwendet werden, um mehrere Elemente eines logischen OR prüfen, wenn ein Element in der Funktion some geprüft wird.

 #main { display: inline-block; } 
ответ дан Dan Philip 14 апр. '17 в 7:27 2017-04-14 07:27

Вместо использования прерывания потока, события размытия/фокусировки или любой другой сложной техники просто сопоставьте поток событий с родством элементов:

 $(document).on("click.menu-outside", function(event){ // Test if target and it parent aren't #menuscontainer // That means the click event occur on other branch of document tree if(!$(event.target).parents().andSelf().is("#menuscontainer")){ // Click outisde #menuscontainer // Hide the menus (but test if menus aren't already hidden) } }); 

Чтобы удалить прослушиватель внешних событий, просто:

 $(document).off("click.menu-outside"); 
8
ответ дан mems 05 июня '13 в 18:05 2013-06-05 18:05

Если вы используете скрипты для IE и FF 3. *, и вы просто хотите знать, произошел ли щелчок в определенной области окна, вы также можете использовать что-то вроде:

 this.outsideElementClick = function(objEvent, objElement){ var objCurrentElement = objEvent.target || objEvent.srcElement; var blnInsideX = false; var blnInsideY = false; if (objCurrentElement.getBoundingClientRect().left >= objElement.getBoundingClientRect().left  objCurrentElement.getBoundingClientRect().right <= objElement.getBoundingClientRect().right) blnInsideX = true; if (objCurrentElement.getBoundingClientRect().top >= objElement.getBoundingClientRect().top  objCurrentElement.getBoundingClientRect().bottom <= objElement.getBoundingClientRect().bottom) blnInsideY = true; if (blnInsideX  blnInsideY) return false; else return true;} 
8
ответ дан Erik 14 авг. '09 в 17:08 2009-08-14 17:08

Verwenden:

 var go = false; $(document).click(function(){ if(go){ $('#divID').hide(); go = false; } }) $("#divID").mouseover(function(){ go = false; }); $("#divID").mouseout(function (){ go = true; }); $("btnID").click( function(){ if($("#divID:visible").length==1) $("#divID").hide(); // Toggle $("#divID").show(); }); 
7
ответ дан webenformasyon 10 янв. '11 в 2:47 2011-01-10 02:47

Подключить к документу прослушиватель событий щелчка. Внутри прослушивателя событий вы можете посмотреть объект события , в частности, event.target , чтобы увидеть, какой элемент был нажат:

 $(document).click(function(e){ if ($(e.target).closest("#menuscontainer").length == 0) { // .closest can help you determine if the element // or one of its ancestors is #menuscontainer console.log("hide"); } }); 
6
ответ дан Salman A 03 мая '12 в 12:21 2012-05-03 12:21

Для более удобного использования и более выразительного кода я создал для него плагин jQuery:

 $('div.my-element').clickOut(function(target) { //do something here... }); 

Hinweis target - это элемент, который пользователь нажал. Но обратный вызов все еще выполняется в контексте исходного элемента, поэтому вы можете использовать этот , как вы ожидали бы в обратном вызове jQuery.

Plugin:

 $.fn.clickOut = function (parent, fn) { var context = this; fn = (typeof parent === 'function') ? parent : fn; parent = (parent instanceof jQuery) ? parent : $(document); context.each(function () { var that = this; parent.on('click', function (e) { var clicked = $(e.target); if (!clicked.is(that)  !clicked.parents().is(that)) { if (typeof fn === 'function') { fn.call(that, clicked); } } }); }); return context; }; 

По умолчанию прослушиватель событий кликов помещается в документ. Однако, если вы хотите ограничить область прослушивателя событий, вы можете передать объект jQuery, представляющий элемент родительского уровня, который будет основным родителем, по которому будут прослушиваться клики. Это предотвращает ненужные прослушиватели событий уровня документа. Очевидно, что это не сработает, если родительский элемент не является родителем вашего начального элемента.

Используйте так:

 $('div.my-element').clickOut($('div.my-parent'), function(target) { //do something here... }); 
5
ответ дан Matt Goodwin 21 апр. '16 в 23:04 2016-04-21 23:04

Я сделал это так: YUI 3:

 // Detect the click anywhere other than the overlay element to close it. Y.one(document).on('click', function (e) { if (e.target.ancestor('#overlay') === null  e.target.get('id') != 'show'  overlay.get('visible') == true) { overlay.hide(); } }); 

Я проверяю, не является ли предком не контейнер элементов виджета,
если цель не та, которая открывает виджет/элемент,
если виджет/элемент, который я хочу закрыть, уже открыт (не так важно).

5
ответ дан Satya Prakash 06 дек. '11 в 16:42 2011-12-06 16:42
 $(document).click(function() { $(".overlay-window").hide(); }); $(".overlay-window").click(function() { return false; }); 

Если вы нажмете на документ, скройте данный элемент, если вы не нажмете на тот же самый элемент.

5
ответ дан Rowan 20 сент. '11 в 21:44 2011-09-20 21:44

Я удивлен, что никто на самом деле не признал событие focusout :

 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <button id="button">Click</button> </body> </html> 
5
ответ дан Jovanni G 12 февр. '18 в 13:39 2018-02-12 13:39

Перейдите на самый популярный ответ, но добавьте

  (e.target != $('html').get(0)) // ignore the scrollbar 

поэтому щелчок по полосе прокрутки не [скрыть или что-либо еще] вашего целевого элемента.

5
ответ дан bbe 26 июля '15 в 0:33 2015-07-26 00:33

Мы внедрили решение, частично основанное на комментарии пользователя выше, который отлично работает для нас. Мы используем его, чтобы скрыть окно поиска/результаты при нажатии вне этих элементов, исключая исходный элемент.

 // HIDE SEARCH BOX IF CLICKING OUTSIDE $(document).click(function(event){ // IF NOT CLICKING THE SEARCH BOX OR ITS CONTENTS OR SEARCH ICON if ($("#search-holder").is(":visible")  !$(event.target).is("#search-holder *, #search")) { $("#search-holder").fadeOut('fast'); $("#search").removeClass('active'); } }); 

Он проверяет, действительно ли окно поиска уже видимо и в нашем случае оно также удаляет активный класс в кнопке поиска/поиска.

4
ответ дан Scott Richardson 08 июля '15 в 4:05 2015-07-08 04:05

Это должно работать:

 $('body').click(function (event) { var obj = $(event.target); obj = obj['context']; // context : clicked element inside body if ($(obj).attr('id') != "menuscontainer"  $('#menuscontainer').is(':visible') == true) { //hide menu } }); 
4
ответ дан Bilal Berjawi 12 янв. '13 в 14:43 2013-01-12 14:43
  • 1
  • 2
  • 3

Weitere Fragen zu Tags oder Frage stellen