Ich habe ein Eingabefeld, das ein benutzerdefiniertes Dropdown-Menü aufruft. Ich möchte die folgende Funktionalität:
- Wenn der Benutzer irgendwo außerhalb des Eingabefelds klickt, sollte das Menü entfernt werden.
- Wenn der Benutzer im Menü auf ein Div klickt, sollte das Menü entfernt werden, und es sollte eine spezielle Verarbeitung erfolgen, die darauf basiert, auf welches Div geklickt wurde.
Hier ist meine Implementierung:
Das Eingabefeld enthält ein onblur()
Ereignis, das das Menü löscht (indem die übergeordneten Elemente innerHTML
auf eine leere Zeichenfolge gesetzt werden), wenn der Benutzer außerhalb des Eingabefelds klickt. Die Divs im Menü haben auch onclick()
Ereignisse, die die spezielle Verarbeitung ausführen.
Das Problem ist, dass die onclick()
Ereignisse niemals ausgelöst werden, wenn auf das Menü geklickt wird, da das Eingabefeld onblur()
zuerst ausgelöst wird und das Menü einschließlich des onclick()
s!
Ich habe das Problem gelöst, indem ich die Menü-Divs onclick()
in onmousedown()
und onmouseup()
Ereignisse aufgeteilt und ein globales Flag bei gedrückter Maus gesetzt habe, das mit der Maus nach oben gelöscht wird, ähnlich wie in dieser Antwort vorgeschlagen . Da onmousedown()
zuvor ausgelöst wurde onblur()
, wird das Flag gesetzt, onblur()
wenn auf eines der Menü-Divs geklickt wurde, nicht jedoch, wenn es sich an einer anderen Stelle auf dem Bildschirm befand. Wenn auf das Menü geklickt wurde, kehre ich sofort zurück, onblur()
ohne das Menü zu löschen, und warte dann, onclick()
bis das Menü ausgelöst wird. An diesem Punkt kann ich das Menü sicher löschen.
Gibt es eine elegantere Lösung?
Der Code sieht ungefähr so aus:
<div class="menu" onmousedown="setFlag()" onmouseup="doProcessing()">...</div>
<input id="input" onblur="removeMenu()" ... />
var mouseflag;
function setFlag() {
mouseflag = true;
}
function removeMenu() {
if (!mouseflag) {
document.getElementById('menu').innerHTML = '';
}
}
function doProcessing(id, name) {
mouseflag = false;
...
}