js点击列表的第一个元素,不起作用,最后一个元素起作用

在尝试实现手风琴菜单时遇到问题,HTML结构包含li列表,但JavaScript绑定的点击事件只对最后一个ul生效。错误在于for循环结束后才执行事件绑定,通过将循环内容放入闭包解决,使得每个按钮都能正确绑定事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在网上看到 手风琴菜单的demo,就想来模仿着做一个

html内容如下:

<div class="container">
        <ul>
            <li class="dropdown">
                <a href="#" data-toggle="dropdown">First Menu <i class="icon-arrow"></i></a>
                <ul class="dropdown-menu">
                    <li><a href="#">Home</a></li>
                    <li><a href="#">About Us</a></li>
                    <li><a href="#">Services</a></li>
                    <li><a href="#">Contact</a></li>
                </ul>
            </li>
            <li class="dropdown">
                <a href="#" data-toggle="dropdown">Second Menu <i class="icon-arrow"></i></a>
                <ul class="dropdown-menu">
                    <li><a href="#">Home</a></li>
                    <li><a href="#">About Us</a></li>
                    <li><a href="#">Services</a></li>
                    <li><a href="#">Contact</a></li>
                </ul>
            </li>
            <li class="dropdown">
                <a href="#" data-toggle="dropdown">Third Menu <i class="icon-arrow"></i></a>
                <ul class="dropdown-menu">
                    <li><a href="#">Home</a></li>
                    <li><a href="#">About Us</a></li>
                    <li><a href="#">Services</a></li>
                    <li><a href="#">Contact</a></li>
                </ul>
            </li>
        </ul>
    </div>

js代码:

window.onload = function() {
            var dropdown = document.querySelectorAll('.dropdown');

            for (var i = 0; i < dropdown.length; i++) {
                var button = dropdown[i].querySelector('a[data-toggle="dropdown"]'),
                    menu = dropdown[i].querySelector('.dropdown-menu'),
                    icon = button.querySelector('.icon-arrow');

                addEvent(button, "click",function(event) {
                    // var menu = this.nextElementSibling,
                    //   icon = this.querySelector('.icon-arrow');

                    if(hasClass(menu,"show")) {
                        menu.classList.remove("show");
                        icon.classList.remove("open") ;                       
                    } else {
                        menu.classList.add("show");
                        icon.classList.add("open");
                    }
                    event.preventDefault();
                });
            }

            function hasClass(ele,className) {  
                return ele.className && new RegExp("(^|\\s)" + className + "(\\s|$)").test(ele.className);  
             }  
        }

发现错误,无论我点击那一个li列表,有效果的<ul class="dropdown-menu"> 总是最后一个,那麽出错原因应是 menu、 icon的获取,但是我还是没找到 原因,于是就修改了一下,改为在button事件中获取menu、button,这次对了,可是我还是不知道我的错在哪?求各位指点。。。。。

原因是:当为button绑定时间时,for循环早就走完了,于是改正一下,将for循环中的内容放在闭包中,改为一下写法:

for (var i = 0; i < dropdown.length; i++) {

                (function() {
                    var button = dropdown[i].querySelector('a[data-toggle="dropdown"]'),
                        menu = dropdown[i].querySelector('.dropdown-menu'),
                        icon = button.querySelector('.icon-arrow');

                    addEvent(button, "click",function(event) {
                        // var menu = this.nextElementSibling,
                        //     icon = this.querySelector('.icon-arrow');

                        if(hasClass(menu,"show")) {
                            menu.classList.remove("show");
                            icon.classList.remove("open") ;                       
                        } else {
                            menu.classList.add("show");
                            icon.classList.add("open");
                        }
                        event.preventDefault();
                    });
                })(i);
}
最后需要贴上css代码

* {
            margin: 0;
            padding: 0;
            font-family: "microsoft yahei";
            box-sizing: border-box;;
        }
        a {
            color: #000;
            text-decoration: none;
        }
        ul {
            list-style: none;
        }
        .container {
            width: 100%;
            height: auto;
        }
        .container> ul {
            width: 320px;
            height: auto;
            margin: 50px auto;
        }
        .container ul .dropdown {
            width: 100%;
            position: relative;
        }
        .container ul .dropdown a {
            display: block;
            width: 100%;
            height: 100%;
            background-color: #2980b9;
            line-height: 40px;
            padding-left: 10px;
            color: #fff;
            box-shadow: 0 -1px 0px #409ad5 inset,0 -1px 0px #20638f inset;
        }
        .container ul .dropdown a .icon-arrow {
            position: absolute;
            right: 10px;
            top: 17px;
            width: 12px;
            height: 12px;
            transition: all .3s;
        }

        .container ul .dropdown a .icon-arrow:after {
            content: "";
            border:6px solid transparent;
            border-top: 6px solid #fff;
        }
        .container ul .dropdown a .icon-arrow.open {
            transform: rotate(-180deg)
        }
        .container ul .dropdown .dropdown-menu {
            display: none
        }
        .container ul .dropdown .dropdown-menu.show{
            display: block
        }
        .container ul .dropdown .dropdown-menu a {
            background-color: #EEEEEE;
            color: #6e6e6e;
            box-shadow: 0 -1px 0px #C3C3C3 inset;
        }



PS:css没有写前缀,测试只在谷歌浏览器下进行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值