2023.12.3使用原生js实现进阶版手风琴菜单(前端冒泡事件处理)

2023.12.3使用原生js实现进阶版手风琴菜单(前端冒泡事件处理)

之前写了一个基础版,现在这个是完全版,补充实现点击空白区域菜单折叠、点击某一菜单其余菜单折叠的功能,该写法可以用于整个网页所有下拉菜单的实现,并且可以结合css灵活进行样式调整。

之前基础版的代码见:2023.12.1 手风琴菜单的简便实现方式
https://editor.csdn.net/md/?articleId=134759727

关注事件冒泡的处理

在早期编写的过程中,未考虑事件冒泡的影响,因此特效时常会出现不稳定执行的情况,检查代码后,怀疑是事件冒泡导致,事件冒泡是指当一个元素上的事件被触发时,它会向父级元素传递,直到传递到文档根节点为止。这意味着如果在子元素上点击某个事件,该事件会依次传递到父元素,所有祖先元素,直到文档根节点。这可能会导致不必要的副作用或影响,特别是当有多个嵌套的元素并且希望在其中一个元素上执行特定操作时。

因此,为了防止事件传递到其他元素,使用 stopPropagation() 方法来阻止事件冒泡。这将防止事件传递到其他元素,仅在当前元素上执行操作。

在每个子菜单上都添加了一个点击事件监听器,用于阻止事件继续传递给其父元素。这确保了只有在子菜单上点击时,才会执行相应的操作,而不会触发父菜单的点击事件。

最后执行效果满意。

附源代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>后端管理网站</title>
    <style>
        /* 隐藏下拉菜单 */
        .submenu {
            display: none;
        }
    </style>
</head>
<body>
    <ul>
        <li><a href="#">首页</a></li>
        <li><a href="#" onclick="toggleMenu(event, 'menu1')">菜单1</a>
            <ul id="menu1" class="submenu">
                <li><a href="#">子菜单1</a></li>
                <li><a href="#">子菜单2</a></li>
                <li><a href="#">子菜单3</a></li>
            </ul>
        </li>
        <li><a href="#" onclick="toggleMenu(event, 'menu2')">菜单2</a>
            <ul id="menu2" class="submenu">
                <li><a href="#">子菜单4</a></li>
                <li><a href="#">子菜单5</a></li>
                <li><a href="#">子菜单6</a></li>
            </ul>
        </li>
        <li><a href="#">菜单3</a></li>
    </ul>

    <script>
        // 获取所有带有 "submenu" 类的元素
        var submenus = document.getElementsByClassName("submenu");

        // 为所有子菜单添加点击事件监听器
        for (var i = 0; i < submenus.length; i++) {
            submenus[i].addEventListener("click", function(event) {
                event.stopPropagation(); // 阻止事件冒泡
            });
        }

        // 点击菜单时切换菜单的显示状态
        function toggleMenu(event, id) {
            var menu = document.getElementById(id);
            if (menu.style.display === 'block') {
                menu.style.display = 'none';
            } else {
                closeAllMenus();
                menu.style.display = 'block';
            }
            event.stopPropagation(); // 阻止事件冒泡
        }

        // 关闭所有菜单
        function closeAllMenus() {
            for (var i = 0; i < submenus.length; i++) {
                submenus[i].style.display = 'none';
            }
        }

        // 在页面点击时关闭所有菜单
        document.addEventListener("click", function() {
            closeAllMenus();
        });
    </script>
</body>
</html>
  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leigh_chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值