Vanilla JavaScript 中的 Dropdowm 菜单 - 用于未知数量的按钮



拜托,你能给我一个香草JS的提示吗?

我通过单击按钮打开了下拉菜单,并有 2 个问题:

1(通过单击具有唯一ID的按钮打开下拉列表。我需要让它在类名上工作,因为它必须在多个按钮上工作- 而且它们的数量是未知的(它们将从 REST API 加载(。 在jQuery中它可以工作吗,但我在Vanilla JS中需要它。

如果我尝试按类名选择按钮,它将返回按钮数组,但我不知道如何从数组中进行选择,单击了哪个按钮。

2(下拉菜单仅在第二次单击按钮时打开(然后它像应该的那样切换(,但第一次单击不执行任何操作。

我的代码在这里:

// 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';
}
});

工作原型在Codepen上: https://codepen.io/vlastapolach/pen/EXdLMy

请问,您有什么想法可以解决这个问题吗?

谢谢!

很简单,你需要一个适用于上下文的通用函数(=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';
}
});

现在,您可以将此函数作为事件处理程序分配给所有元素:

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

请注意,NodeList.forEach 是相当新的,可以使用 [].slice 创建一个真正的数组...

并且您需要手动将处理程序分配给新添加的元素,或者您需要侦听窗口并追溯目标:

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