JavaScript实现二级菜单的制作

作者:竹影

时间:2026-10-25

浏览:327

本文详细介绍如何使用JavaScript实现一个具有展开与收起动画效果的二级菜单。通过获取DOM元素、监听点击事件、动态修改元素高度以及利用定时器实现平滑过渡,完整展示了从结构搭建到交互逻辑的实现过程。

文章目录

JavaScript实现二级菜单的制作

本文分享了一段使用JavaScript实现二级菜单效果的完整代码,供读者参考学习。

最终实现的界面效果如下图所示:

JavaScript实现二级菜单的制作

该二级菜单的核心交互逻辑如下:

当用户点击某个菜单项时,系统会自动收起当前已展开的菜单内容,并展开当前被点击的菜单项。

具体实现思路如下:

我们可以分步骤逐步实现。

界面初始化与结构搭建

第一步,初始化界面结构。首先展示所有菜单项展开的状态,因为菜单的显示与隐藏是通过overflow:hidden属性控制的。需要注意的是,不能将所有菜单项使用同一种类型的容器,否则会增加JavaScript代码的编写难度。由于交互逻辑是点击绿色区域以控制白色区域的展开或收起,因此需要将每个天数及其对应的课程信息包裹在一个div父容器中。初始化时,设置容器的高度等于span标签的高度,并设置overflow:hidden属性,具体效果可参考下图及下方代码。

JavaScript实现二级菜单的制作

JavaScript交互逻辑实现

第二步,编写JavaScript交互逻辑。确保点击某个菜单项时,其状态由收起变为展开。由于菜单项是span元素,若要显示其父容器div内的所有内容,首先需要通过document.getElementsByTagName("span")获取所有的span元素。接着,利用for循环遍历每个span,在span的onclick事件响应函数中,通过parentNode属性获取对应的父容器div,并将其高度设置为该span的scrollHeight值。

菜单展开与收起逻辑

第三步,实现点击展开时自动收起其他已展开项。为此,需要引入一个变量now来记录上一次被点击的菜单项,初始值设为null。如果now不等于当前点击的span元素,则获取now对应的父容器,将其高度设置为span的高度,随后展开当前点击的span(展开逻辑已在第二步中说明);如果now等于当前点击的span,则获取其父容器的高度,若该高度等于span的高度,则将其高度设置为scrollHeight值(即收起),否则将其高度设置为span的高度(即展开)。

动画效果实现

第四步,添加动画效果。设置定时器,在调整父容器高度增加或减少的过程中调用。当父容器高度达到span的高度或达到scrollHeight值时,关闭定时器(可以设置两个独立的定时器分别处理展开和收起)。

完整代码如下:

完整代码示例


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .container {
            width: 300px;
            height: 700px;
            margin: 100px auto;
        }

        .container div {
            height: 43px;
            overflow: hidden;
        }

        .container div span {
            width: 150px;
            height: 40px;
            line-height: 40px;
            border-radius: 15px;
            display: block;
            text-align: center;
            background-color: rgba(104, 250, 201, 0.849);
            cursor: pointer;
        }

        a {
            width: 150px;
            height: 40px;
            line-height: 40px;
            text-decoration: none;
            display: block;
            text-align: center;
        }
    </style>
</head>

<body>
    <div class="container">
        <div id="">
            <span id="one">周一</span>
            <a href="">可视化</a>
            <a href="">可视化</a>
        </div>
        <div id="">
            <span id="two">周二</span>
            <a href="">算法设计</a>
            <a href="">图形学</a>
            <a href="">计组课设</a>
            <a href="">操作系统</a>
        </div>
        <div id="">
            <span id="three">周四</span>
            <a href="">形势与政策</a>
            <a href="">操作系统</a>
        </div>
        <div id="">
            <span id="four">周五</span>
            <a href="">算法设计</a>
        </div>
    </div>

    <script>
        let menu = document.getElementsByTagName("span");
        let now = null;
        for (let i = 0; i < menu.length; i++) {
            menu[i].onclick = function () {
                let par = menu[i].parentNode;
                if (now === i) {
                    if (par.style.height === "43px") {
                        open(par);
                    }
                    else {
                        close(par);
                    }
                }
                else {
                    if (now !== null) {
                        close(menu[now].parentNode);
                    }
                    open(par);
                    now = i;
                }
            }
        }

        function open(par) {
            let tem = setInterval(() => {
                let num = par.offsetHeight;
                if (num >= par.scrollHeight) {
                    clearInterval(tem);
                }
                par.style.height = num + 1 + "px";
            }, 7);
        }

        function close(par) {
            let tem = setInterval(() => {
                let num = par.offsetHeight;
                if (num <= 43) {
                    clearInterval(tem);
                    return;
                }
                par.style.height = num - 1 + "px";
            }, 7);
        }

    </script>
</body>

</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也欢迎大家继续支持本站。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章