我试图在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编写多个函数,而不是使用类,我就不可能让所有代码一起工作。
发布于 2017-01-21 19:08:24
drop是一个nodeList,它用sub类表示元素。
drop中的每个元素都可以使用其index访问。=> drop[i]
for (i = 0; i < drop.length; i++){
//process drop[i]
}我建议您使用以下方法:
您需要为每个带有click类的li附加一个sub事件。问题是,当调用subMenu函数时,会创建一个context。如果您不使用let键,您将看到收到错误,因为当您单击li项时,i在for循环中的最后一个值在本例中将是2。这是个常见的问题。请看这里:圈内闭包。对于这种类型的问题,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关键字,则应该使用立即调用函数表达式。
如果您想要在没有整个菜单再次关闭的情况下对链接进行select,则必须使用event.target属性,该属性指示发起事件的DOM元素。因此,只有在单击带有toggle类的li而不是ul子程序时才应用sub事件。
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>
发布于 2017-01-21 19:10:49
你犯了一些错误!
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;https://stackoverflow.com/questions/41783285
复制相似问题