Wie erkenne ich ein klicken Sie außerhalb eines Elements?
Habe ich einige HTML-Menüs, die ich vollständig angezeigt, wenn ein Benutzer klickt auf die Leiter, diese Menüs. Ich möchte diese Elemente auszublenden, wenn der Benutzer auf eine Stelle außerhalb des Menüs' Bereich.
Ist so etwas möglich mit jQuery?
$("#menuscontainer").clickOutsideThisElement(function() {
//Hide the menus
});
Hier ist ein Beispiel für diese Strategie: jsfiddle.net/tedp/aL7Xe/1
Als Tom erwähnt, werden Sie wollen, Lesen Sie css-tricks.com/dangers-stopping-event-propagation vor der Verwendung dieses Ansatzes. Das jsfiddle tool ist ziemlich cool aber.
Holen Sie sich eine Referenz auf das element und dann event.Ziel, und endlich != oder == die beiden von Ihnen führen dann entsprechend zu Programmieren..
Ich empfehle github.com/gsantiago/jquery-clickout 🙂
Versuchen
Als Tom erwähnt, werden Sie wollen, Lesen Sie css-tricks.com/dangers-stopping-event-propagation vor der Verwendung dieses Ansatzes. Das jsfiddle tool ist ziemlich cool aber.
Holen Sie sich eine Referenz auf das element und dann event.Ziel, und endlich != oder == die beiden von Ihnen führen dann entsprechend zu Programmieren..
Ich empfehle github.com/gsantiago/jquery-clickout 🙂
Versuchen
event.path
. http://stackoverflow.com/questions/152975/how-do-i-detect-a-click-outside-an-element/43405204#43405204InformationsquelleAutor |
Du musst angemeldet sein, um einen Kommentar abzugeben.
Anhängen klicken Sie auf Ereignis, um das Dokument Körper, der schließt das Fenster. Befestigen Sie eine separate click-Ereignis, um die container, und hält die Ausbreitung des Dokuments Körper.
Dies bricht nicht Verhalten, etwas in #menucontainer, da ist es an der Unterseite der Ausbreitung Kette für alles, was in ihm ist.
seine sehr typischen, aber Sie verwenden sollten
$('html').click()
nicht Körper. Der Körper hat immer die Höhe des Inhalts. Es ist nicht viel Inhalt oder der Bildschirm ist sehr hoch, es funktioniert nur auf den Teil gefüllt, die durch den Körper.Ich bin auch überrascht, dass diese Lösung bekam so viele Stimmen. Dieses scheitern wird für jedes element außerhalb, hat stopPropagation jsfiddle.net/Flandre/vaNFw/3
Philip Walton erklärt sehr gut, warum diese Antwort ist nicht die beste Lösung: css-tricks.com/dangers-stopping-event-propagation
InformationsquelleAutor
Können Sie hören für eine klicken Sie auf Veranstaltung auf
document
und dann stellen Sie sicher, dass#menucontainer
ist nicht ein Vorfahre oder das Ziel des angeklickten element mit.am nächsten()
.Wenn es nicht ist, dann das angeklickte element ist außerhalb der
#menucontainer
- und Sie können sicher verstecken.Bearbeiten – 2017-06-23
Können Sie auch das clean up nach dem event-listener, wenn Sie planen, schließen Sie das Menü und wollen zu stoppen, warten auf Ereignisse. Diese Funktion wird sauber, nur die neu erstellten listener aus, bewahrt dabei alle anderen auf die Zuhörer auf
document
. Mit ES2015 syntax:Bearbeiten – 2018-03-11
Für diejenigen, die nicht wollen, um jQuery verwenden. Hier ist der obige code in plain vanillaJS (ECMAScript6).
HINWEIS:
Diese basiert auf Alex Kommentar, nur mit
!element.contains(event.target)
anstelle der jQuery-Teil.Aber
element.closest()
ist jetzt auch erhältlich in allen gängigen Browsern (in der W3C-version unterscheidet sich ein wenig von der jQuery).Polyfills kann hier gefunden werden: https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
Ich habe tatsächlich landete mit dieser Lösung, weil es besser unterstützt mehrere Menüs auf der gleichen Seite, wo Sie auf ein zweites Menü, während eine erste geöffnet ist, lassen Sie die erste offen in die stopPropagation Lösung.
Dies ist eine sehr gute Lösung für mehrere Elemente auf der Seite.
Ausgezeichnete Antwort. Dies ist der Weg zu gehen, wenn Sie haben mehrere Elemente, die Sie schließen möchten.
Ohne jQuery -
!element.contains(event.target)
mit - Knoten.enthält()InformationsquelleAutor
Den anderen Lösungen hier für mich nicht funktioniert also musste ich nutzen:
Dieser arbeitete für mich, außer ich Hinzugefügt
&& !$(event.target).parents("#foo").is("#foo")
innerhalb derIF
- Anweisung, so dass alle child-Elemente nicht schließen Sie das Menü, wenn Sie angeklickt wird.Deine Antwort-kann wertvoll sein du hast also die 5, aber ich war verwirrt von Ihrer Antwort. und wer MBJ. Ich war auf der Suche zu erstellen, die bessere Lösung basierend auf Ihre Antwort.
Die prägnante Verbesserung Griff tief die Verschachtelung ist die Verwendung
.is('#foo, #foo *')
, aber ich empfehle, nicht verbindlich, klicken Sie auf Handler, um dieses Problem zu lösen.!$(event.target).closest("#foo").length
wäre besser und entfällt die Notwendigkeit für @honyovk ist zusätzlich.InformationsquelleAutor
Ich habe eine Anwendung, die funktioniert ähnlich wie Eran Beispiel, außer ich lege das click-Ereignis für den Körper, wenn ich öffnen Sie das Menü... Irgendwie so:
Mehr Informationen auf jQuery ist
()
- FunktionEs hilft zu setzen, event.stopProgagantion (), bevor Sie eine Bindung die click-listener auf den Körper.
Das problem mit diesem ist, dass "man" bezieht sich auf das jQuery-Methode zum hinzufügen von Ereignissen zu einem array mehrere Male. Also, wenn Sie klicken Sie auf das Menü um es zu öffnen mehr als einmal, das Ereignis gebunden ist, um den Körper wieder und versuche zu verstecken, das Menü mehrere Male. Ein failsafe sollte angewendet werden, um dieses Problem zu beheben.
Nach der Bindung mit
.one
-- innerhalb der$('html')
handler -- schreiben Sie eine$('html').off('click')
.Ich glaube nicht, dass das hilft. Die
one
- handler wird automatisch aufgerufenoff
(wie es hier in den jQuery docs).InformationsquelleAutor
Funktioniert bei mir einwandfrei.
blur ist eine Bewegung außerhalb der
#menucontainer
wurde die Frage über einen Klickblur ist nicht ein verschieben außerhalb des Behälters. Blur ist das Gegenteil von Fokus, Sie denken mouseout. Diese Lösung funktioniert besonders gut für mich, wenn ich war die Schaffung von "click to edit" - text, wo ich ausgelagert hin und her zwischen text-und Eingabefelder klickt.
Ich hatte, um
tabindex="-1"
zu den#menuscontainer
machen, damit es funktioniert. Es scheint, dass, wenn man einen input-tag im container und klicken Sie auf es, der container wird ausgeblendet.das mouseleave-Ereignis ist besser geeignet für die Menüs und Container (ref: w3schools.com/jquery/...)
InformationsquelleAutor
Gibt es jetzt ein plugin für die: außerhalb von Veranstaltungen (blog-post)
Folgendes geschieht, wenn ein clickoutside handler (WLOG) ist gebunden an ein element:
Also keine Ereignisse angehalten werden, die Ausbreitung und weitere klicken Sie auf - Handler verwendet werden kann "über" dem element mit außen-handler.
Tolles plugin. Funktionierte perfekt. Die Nutzung ist in etwa so:
$( '#element' ).on( 'clickoutside', function( e ) { .. } );
InformationsquelleAutor
Nach der Forschung habe ich festgestellt, drei Arbeitslösungen (ich vergaß die Seite links für Referenz)
Erste Lösung
Zweite Lösung
Dritte Lösung
Ich werde versuchen, die Dritte Lösung mit mehreren Elementen
document.getElementsByClassName
, wenn jemand eine Ahnung hat, bitte teilen.Sie müssten, um eine Schleife durch die überprüfung jeder.
Mochte die Dritte Lösung, aber das klicken auslöst, bevor mein div hat begonnen, um zu zeigen, welche versteckt es wieder, keine Ahnung warum?
Die Dritte erlaubt die Konsole.anmelden, sicher, aber es lässt Sie nicht eigentlich schließen, indem Sie die Einstellung display auf none - denn es wird dies tun, bevor das Menü angezeigt wird. Haben Sie eine Lösung dafür?
InformationsquelleAutor
Dieser arbeitete für mich perfekt!!
InformationsquelleAutor
Ich glaube nicht, dass das, was Sie wirklich brauchen, ist das Menü zu schließen, wenn der Benutzer klickt außerhalb; was Sie brauchen, ist für das Menü zu schließen, wenn der Benutzer klickt auf eine beliebige Stelle auf der Seite. Wenn Sie klicken Sie auf die Menü oder von der Speisekarte sollte es in der Nähe richtig?
Finden keine befriedigenden Antworten oben aufgefordert, mir zu schreiben, in diesem blog-post den anderen Tag. Für die mehr pedantisch, es gibt eine Reihe von Einschränkungen zu beachten:
body { margin-left:auto; margin-right: auto; width:960px;}
InformationsquelleAutor
Als ein weiteres Plakat sagte, es gibt eine Menge Fallstricke, vor allem, wenn das element, das Sie anzeigen lassen wollen (in diesem Fall ein Menü) hat interaktive Elemente.
Ich habe festgestellt, das folgende Methode Recht robust:
InformationsquelleAutor
Eine einfache Lösung für die situation ist:
Dem obigen Skript blendet die
div
wenn außerhalb derdiv
click-Ereignis ausgelöst wird.Können Sie unter den folgenden blog-für mehr Informationen : http://www.codecanal.com/detect-click-outside-div-using-javascript/
InformationsquelleAutor
Solution1
Anstatt über das Ereignis.stopPropagation() kann einige Nebenwirkungen, nur definieren Sie ein einfaches flag-variable und fügen Sie eine
if
Zustand. Ich getestet und funktionierte einwandfrei ohne irgendwelche Nebenwirkungen von stopPropagation:Solution2
Mit nur einem einfachen
if
Zustand:InformationsquelleAutor
Überprüfen Sie im Fenster auf Ereignis-Ziel (sollte es propagieren, um das Fenster, so lange, wie es nicht geschlagen, überall sonst), und sicherzustellen, dass es nicht eine der Menü-Elemente. Wenn nicht, dann bist du außerhalb Ihres Menüs.
Oder überprüfen Sie die position des klicken Sie auf, und sehen, ob es enthalten ist im Menü Bereich.
InformationsquelleAutor
Hatte ich Erfolg mit so etwas wie dies:
Die Logik ist: wenn
#menuscontainer
gezeigt wird, binden Sie einen click-Ereignishandler, um den Körper, verbirgt sich#menuscontainer
nur, wenn das Ziel (der klicken) Sie ist nicht ein Kind von ihm.InformationsquelleAutor
Als Variante:
Er hat kein problem mit stoppen der ereignisübertragung und besser unterstützt mehrere Menüs auf der gleichen Seite, wo Sie auf ein zweites Menü, während eine erste geöffnet ist, lassen Sie die erste offen in die stopPropagation Lösung.
InformationsquelleAutor
Fand ich diese Methode in einigen jQuery-Kalender-plugin.
InformationsquelleAutor
Wenn Sie scripting für den IE und FF 3.* und Sie wollen einfach nur wissen, ob die Klicks innerhalb einer bestimmten Feld-Bereich, Sie können auch etwas wie:
InformationsquelleAutor
Statt mit flow-Unterbrechung, blur/focus event oder jede andere knifflige Technik, einfach match event flow mit dem element Verwandtschaft:
Zu entfernen, klicken Sie außerhalb der Ereignis-listener, einfach:
Es ist eine redundante check here. wenn das element ist in der Tat
#menuscontainer
Sie sind immer noch durch Sie, die Eltern. Sie sollten zuerst überprüfen, und wenn es nicht das element, dann gehen Sie den DOM-Baum.Richtig ! Können Sie ändern den Zustand zu
if(!($(event.target).is("#menuscontainer") || $(event.target).parents().is("#menuscontainer"))){
. Es ist eine kleine Optimierung, sondern tritt nur wenige Male in Ihrem Programm Leben : für jeden Klick, wenn dieclick.menu-outside
- Ereignis registriert ist. Es ist länger (+32 chars) und nicht mit der Methode VerkettungInformationsquelleAutor
Verwenden:
InformationsquelleAutor
Haken ein click-Ereignis-listener auf das Dokument. Innerhalb der Ereignis-listener können Sie die event-Objekt, insbesondere die event.Ziel, um zu sehen, welches element geklickt wurde:
InformationsquelleAutor
Wenn Sie klicken Sie auf das Dokument, verbergen element, es sei denn, Sie klicken auf das gleiche element.
InformationsquelleAutor
Upvote für die beliebteste Antwort, aber fügen Sie
also, klicken Sie auf die scroll-Leiste nicht [ausblenden oder was auch immer] Ihr Ziel-element.
InformationsquelleAutor
Einfachere Nutzung und mehr Ausdruckskraft code, ich habe ein jQuery-plugin dafür:
Hinweis: Ziel ist das element, das der Benutzer tatsächlich klickt. Aber callback-wird noch ausgeführt-in dem Kontext des ursprünglichen Elements, so können Sie nutzen diese als Sie erwarten würden, in ein jQuery-callback.
Plugin:
Standardmäßig das click-Ereignis-listener auf dem Dokument. Allerdings, wenn Sie wollen, beschränken Sie die Ereignis-listener-Bereich, die Sie übergeben können, in ein jQuery-Objekt, das einem übergeordneten element, das die Obere Elternteil, bei dem Klicks gehört werden. Dies verhindert unnötige document-level-event-Listener. Offensichtlich funktioniert es nicht, es sei denn, das übergeordnete element geliefert wird, ist ein Elternteil von Ihr erstes element.
Verwenden, etwa so:
InformationsquelleAutor
Habe ich es so in YUI 3:
Ich bin der überprüfung, ob Vorfahr ist nicht das widget-element-container,
wenn das Ziel ist nicht, die öffnen Sie die widget/element
wenn widget/element will ich schließen-ist bereits geöffnet (nicht so wichtig).
InformationsquelleAutor
Wenn jemand neugierig ist, hier ist der javascript-Lösung(es6):
und es5, nur für den Fall:
});
InformationsquelleAutor
Habe ich folgenden script mit jQuery.
Unten finden Sie den HTML-code
Können Sie das tutorial Lesen, hier
InformationsquelleAutor