addEventListener with getElementsByClassName

时间:2017-01-21 19:02:48

标签: javascript html

我正在尝试在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编写多个函数而不是使用类。

2 个答案:

答案 0 :(得分:2)

dropnodeList,代表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元素。因此,只有当您点击toggleli班级而不是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;