2017-07-09 3 views
2

bitte, können Sie mir einen Tipp mit Vanilla JS geben?Dropdowm Menü in Vanille JavaScript - für unbekannte Anzahl von Tasten

Ich habe Drop-Down-Menü Öffnung über den Button klicken und haben zwei Probleme:

1) Dropdown wird durch Klicken auf die Schaltfläche mit eindeutigen ID zu öffnen. Ich muss es arbeiten auf Klasse Name zu bekommen, weil es auf mehrere Tasten arbeiten muss - und die Anzahl von ihnen ist unbekannt (sie werden von REST API geladen). In jQuery funktioniert es, aber ich brauche es in Vanilla JS.

Wenn ich versuche, Knopf nach Klassennamen zu wählen, wird es Array von Schaltflächen zurückgeben, aber ich weiß nicht, wie aus Array auszuwählen, auf welche Schaltfläche geklickt wurde.

2) Dropdown-Menü öffnet nur auf den zweiten Klick auf die Schaltfläche (und dann ist es Umschalten wie es sollte), aber der erste Klick tut nichts.

Mein Code ist hier:

// select Button - now by ID - but I need unknown number of buttons - from REST API - and the code working for all of them 
var btn = document.getElementById("dropBtn1"); 

// select Dropdown menu - next to the button - to be sure it will open the right menu no matter which button will be pressed 
var menu = btn.nextSibling; 
while(menu && menu.nodeType != 1) { 
    menu = menu.nextSibling 
} 

//toggle dropdown menu open/close 
btn.addEventListener("click", function() { 
    if (menu.style.display == 'none') { 
    menu.style.display = 'block'; 
    } 
    else { 
    menu.style.display = 'none'; 
    } 
}); 

Und funktionierender Prototyp ist hier auf Codepen: https://codepen.io/vlastapolach/pen/EXdLMy

Bitte, haben Sie irgendwelche Ideen, wie dieses Problem beheben?

Vielen Dank!

+1

ersten Mal Click-Handler läuft menu.style.display leer ist, während Ihr Code erwartet menu.style.display == 'none', damit die Anzeige in den Block – derloopkat

+0

geändert werden kann. Danke, Sie haben Recht. Es ist jetzt gelöst nach Jonas - nicht nach == 'none' zu überprüfen, sondern für! = 'Block' –

Antwort

1

Ganz einfach, benötigen Sie eine allgemeine Funktion, die auf dem Kontext arbeitet (= this):

//toggle dropdown menu open/close 
function toggle() { 
    var btn=this; 

    var menu = btn.nextSibling; 
    while(menu && menu.nodeType != 1) { 
    menu = menu.nextSibling 
    } 

    if(!menu) return; 

    if (menu.style.display != 'block') {//fix 2) 
    menu.style.display = 'block'; 
    } else { 
    menu.style.display = 'none'; 
    } 
}); 

Jetzt können Sie diese Funktionen als Event-Handler zuweisen auf alle Elemente:

window.addEventListener("DOMContentLoaded",function(){ 

    document.querySelectorAll(".sth").forEach(function(btn){ 
    btn.addEventListener("click",toggle,true); 
    }); 
}); 

Beachten Sie, dass NodeList.forEach ganz neu ist, verwenden [] .slice ein echtes Array erstellen ...

Und Sie müssen die Handl zuweisen ers an die neu manuell hinzugefügten Elemente, oder müssen Sie auf Fenster hören und das Ziel zurückverfolgen:

window.onclick=function(event){ 
    if(event.target.classList.contains("sth")){ 
    toggle.call(event.target); 
    } 
}; 
+0

Hallo Jonas, vielen Dank. Es hat das erste Problem gelöst - jetzt arbeitet es an allen Knöpfen :) Bitte, können Sie mir mit Problem # 2 helfen? Es öffnet das Dropdown-Menü nur bei einem zweiten Klick auf die Schaltfläche. Und bitte, Frage # 3 - Gibt es eine einfache Möglichkeit, das Dropdown-Menü zu schließen, wenn ich außerhalb des Dropdown-Menüs klicke? (Jetzt schließt es nur, wenn ich wieder auf den Knopf klicke, damit ich 3 Dropdown-Listen gleichzeitig geöffnet habe ...) –

+0

@vlasta po schau dir die Zeile an, die mit 2) kommentiert wird ... fix ... –

+0

groß, das zweite Problem ist mit wechselnder Bedingung gemacht, um nach 'Block' statt 'None' zu testen. Danke Jonas –

Verwandte Themen