我正在尝试在javascript(vanilla)中创建一个下拉菜单。我知道如何在CSS中做到这一点,但如果我不尝试用Javascript做事,我将永远不会真正理解Javascript,因此问题。
我的问题是我无法弄清楚如何使用getElementsByClassName
中的数组并将其循环到仅定位被点击的<li>
。我用谷歌搜索直到我的头疼,这是由于缺乏对如何使用循环的onclick
事件获取/使用数组的理解/知识。如果有人能帮助我解决这个问题
function startUp() {
subMenu();
}
function subMenu() {
var menu = document.getElementById('Menu').addEventListener('click', subMenu);
var drop = document.getElementsByClassName('sub');
for (i = 0; i < drop.length; i++){
drop += drop.length;
if (drop.style.display === 'none') {
drop.style.display = 'inline-block';
}else {
drop.style.display = 'none';
}
}
}
window.onload = startUp;
<nav id="Menu">
<ul>
<li>Home</li>
<li>Members</li>
<li>Gallery
<ul class="sub" style="display: none;">
<li>link</li>
<li>link 1</li>
<li>link 2</li>
<li>link 3</li>
</ul>
</li>
<li>Contact
<ul class="sub" style="display: none;">
<li>E-Mail</li>
</ul>
</li>
<li>Steam Community</li>
<li>Youtube</li>
</ul>
</nav>
我整个下午都尝试了多种不同的代码变体,我似乎无法全部合作,而无需为ID编写多个函数而不是使用类。
答案 0 :(得分:2)
drop
是nodeList
,代表sub
类的元素。
drop
中的每个元素都可以使用其index
进行访问。 =&GT; drop[i]
for (i = 0; i < drop.length; i++){
//process drop[i]
}
我建议你使用以下方法:
您需要为每个click
级别li
附加sub
个事件。问题是,当调用subMenu
函数时,会创建一个context
。如果您不使用let
键,则会看到您收到错误,因为当您点击li
项时,for循环中i
的最后一个值将为2
在这种情况下。这是一个常见的问题。请看这里:closures inside loops。对于此类问题,ECMS6会提供let
个关键字。
function startUp() {
subMenu();
}
function subMenu() {
var drop = document.getElementsByClassName('sub');
for(let i=0;i<drop.length;i++){
drop[i].addEventListener('click', function(){
if(drop[i].querySelector('ul').style.display==='none'){
drop[i].querySelector('ul').style.display='block';
}
else
drop[i].querySelector('ul').style.display='none';
});
};
}
window.onload = startUp;
<nav id="Menu">
<ul>
<li>Home</li>
<li>Members</li>
<li class="sub">Gallery
<ul style="display: none;">
<li>link</li>
<li>link 1</li>
<li>link 2</li>
<li>link 3</li>
</ul>
</li>
<li class="sub">Contact
<ul style="display: none;">
<li>E-Mail</li>
</ul>
</li>
<li>Steam Community</li>
<li>Youtube</li>
</ul>
</nav>
如果您不想使用let
关键字,则应使用Immediately-invoked function expression。
如果您希望select
链接没有重新关闭整个菜单,则必须使用event.target
属性,该属性指示启动事件的DOM元素。因此,只有当您点击toggle
与li
班级而不是sub
孩子时,才会应用ul
个活动。
function startUp() {
subMenu();
}
function subMenu() {
var drop = document.getElementsByClassName('sub');
for(var i=0;i<drop.length;i++){
(function(index){
drop[index].addEventListener('click', function(e){
if(e.target.className=="sub"){
if(drop[index].querySelector('ul').style.display==='none'){
drop[index].querySelector('ul').style.display='block';
}
else
drop[index].querySelector('ul').style.display='none';
}
});
})(i);
};
}
window.onload = startUp;
<nav id="Menu">
<ul>
<li>Home</li>
<li>Members</li>
<li class="sub">Gallery
<ul style="display: none;">
<li>link</li>
<li>link 1</li>
<li>link 2</li>
<li>link 3</li>
</ul>
</li>
<li class="sub">Contact
<ul style="display: none;">
<li>E-Mail</li>
</ul>
</li>
<li>Steam Community</li>
<li>Youtube</li>
</ul>
</nav>
答案 1 :(得分:0)
你有一些错误!
function startUp() {
var menu = document.getElementById('Menu');//Set handler here
menu.addEventListener('click', subMenu);
subMenu();
}
function subMenu() {
var drop = document.getElementsByClassName('sub');
for (i = 0; i < drop.length; i++){
drop += drop.length; //???? drop it is array of htmlElements if you want get one elemnt use drop[i];
if (drop.style.display === 'none') {
drop.style.display = 'inline-block';
}else {
drop.style.display = 'none';
}
}
}
window.onload = startUp;