RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1412774
Accepted
vegasmoscow
vegasmoscow
Asked:2022-07-23 05:03:31 +0000 UTC2022-07-23 05:03:31 +0000 UTC 2022-07-23 05:03:31 +0000 UTC

如何让垂直的多级菜单平滑展开?

  • 772

有一个具有无限嵌套级别的垂直菜单目录。我遇到了一个问题 - 我无法为其打开和关闭设置动画。该属性display也没有动画height。有另一种选择max-height,但这一切都太麻烦了。

这是一个示例,所有项目Sub都有一个嵌套的子菜单。

document.querySelector('.root-nav').onclick = function(event) {

    if (event.target.nodeName !== 'SPAN') return

    closeAllSubMenu(event.target.nextElementSibling)
    event.target.classList.add('submenu-active-span')
    event.target.nextElementSibling.classList.toggle('submenu-active')

}

function closeAllSubMenu(currentMenu = null) {
    const parents = []

    if (currentMenu) {
        let currentParent = currentMenu.parentNode
        while(currentParent) {
            if (currentParent.classList.contains('root-nav')) break
            if (currentParent.nodeName === 'UL') parents.push(currentParent)
            currentParent = currentParent.parentNode
        }
    }

    const allSubMenu = document.querySelectorAll('.root-nav ul')
    Array.from(allSubMenu).forEach(item => {
        if (item !== currentMenu && !parents.includes(item)) {
            item.classList.remove('submenu-active')
            if (item.previousElementSibling.nodeName === 'SPAN') {
                item.previousElementSibling.classList.remove('submenu-active-span')
            }
        }
    })
}
* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}
.root-nav {
    width: 300px;
}

.root-nav li {
    list-style-type: none;
    background-color: coral;
    padding-left: 0;
    position: relative;
}

.root-nav a, .root-nav span {
    text-decoration: none;
    color: white;
    display: block;
    padding: 5px 10px;
    cursor: pointer;
}

.root-nav ul {
    display: none;
    width: 100%;
}

ul.submenu-active {
    display: block;
    padding-left: 20px;
}

span.submenu-active-span {
    background-color: crimson;
}
    <ul class="root-nav">
        <li><a href="#">Link 1</a></li>
        <li>
            <span>Sub 1</span>
            <ul>
                <li><a href="#">Link 10</a></li>
                <li><a href="#">Link 20</a></li>
                <li><a href="#">Link 30</a></li>
                <li><a href="#">Link 40</a></li>
            </ul>
        </li>
        <li><a href="#">Link 3</a></li>
        <li><a href="#">Link 4</a></li>
        <li>
            <span>Sub 2</span>
            <ul>
                <li><a href="#">Link 50</a></li>
                <li><a href="#">Link 60</a></li>
                <li>
                    <span>Sub 20</span>
                    <ul>
                        <li><a href="#">Link 100</a></li>
                        <li><a href="#">Link 200</a></li>
                        <li>
                            <span>Sub 3</span>
                            <ul>
                                <li><a href="#">Link 1000</a></li>
                                <li><a href="#">Link 2000</a></li>
                                <li><a href="#">Link 3000</a></li>
                                <li><a href="#">Link 4000</a></li>
                            </ul>
                        </li>
                        </li>
                        <li><a href="#">Link 400</a></li>
                    </ul>
                </li>
                <li><a href="#">Link 80</a></li>
            </ul>
        </li>
    </ul>

也许有人知道如何平滑地显示无限嵌套的垂直菜单?

javascript вёрстка
  • 1 1 个回答
  • 60 Views

1 个回答

  • Voted
  1. Best Answer
    Alexander Kiselev
    2022-07-23T21:00:58Z2022-07-23T21:00:58Z

    可以使用 max-height + overflow: hidden 设置动画。

    展开子菜单会非常好。

    document.querySelector('.root-nav').onclick = function(event) {
    
        if (event.target.nodeName !== 'SPAN') return
    
        closeAllSubMenu(event.target.nextElementSibling)
        event.target.classList.add('submenu-active-span')
        event.target.nextElementSibling.classList.toggle('submenu-active')
    
    }
    
    function closeAllSubMenu(currentMenu = null) {
        const parents = []
    
        if (currentMenu) {
            let currentParent = currentMenu.parentNode
            while(currentParent) {
                if (currentParent.classList.contains('root-nav')) break
                if (currentParent.nodeName === 'UL') parents.push(currentParent)
                currentParent = currentParent.parentNode
            }
        }
    
        const allSubMenu = document.querySelectorAll('.root-nav ul')
        Array.from(allSubMenu).forEach(item => {
            if (item !== currentMenu && !parents.includes(item)) {
                item.classList.remove('submenu-active')
                if (item.previousElementSibling.nodeName === 'SPAN') {
                    item.previousElementSibling.classList.remove('submenu-active-span')
                }
            }
        })
    }
    * {
        padding: 0;
        margin: 0;
        box-sizing: border-box;
    }
    .root-nav {
        width: 300px;
    }
    
    .root-nav li {
        list-style-type: none;
        background-color: coral;
        padding-left: 0;
        position: relative;
        border: 1px solid;
    }
    
    .root-nav a, .root-nav span {
        text-decoration: none;
        color: white;
        display: block;
        padding: 5px 10px;
        cursor: pointer;
    }
    
    .root-nav ul {
        height: 100%;
        width: 100%;
        padding-left: 20px;
        max-height: 0px; /* <-- Устанавливаем по умолчанию максимальную высоту 0 */
        transition: max-height 0.15s ease-out; /* <-- Добавляем плавность изменения */
        overflow: hidden; /* <-- скрываем внутренний контент */
    }
    
    
    span.submenu-active-span {
        background-color: crimson;
    }
    
    span.submenu-active-span+ul.submenu-active {
        max-height: 500px; /* <-- раскрываем блок */
        transition: max-height 0.25s ease-in; /* <-- добавляем правила плавности для закрытия меню */
    }
    <ul class="root-nav">
            <li><a href="#">Link 1</a></li>
            <li>
                <span>Sub 1</span>
                <ul>
                    <li><a href="#">Link 10</a></li>
                    <li><a href="#">Link 20</a></li>
                    <li><a href="#">Link 30</a></li>
                    <li><a href="#">Link 40</a></li>
                </ul>
            </li>
            <li><a href="#">Link 3</a></li>
            <li><a href="#">Link 4</a></li>
            <li>
                <span>Sub 2</span>
                <ul>
                    <li><a href="#">Link 50</a></li>
                    <li><a href="#">Link 60</a></li>
                    <li>
                        <span>Sub 20</span>
                        <ul>
                            <li><a href="#">Link 100</a></li>
                            <li><a href="#">Link 200</a></li>
                            <li>
                                <span>Sub 3</span>
                                <ul>
                                    <li><a href="#">Link 1000</a></li>
                                    <li><a href="#">Link 2000</a></li>
                                    <li><a href="#">Link 3000</a></li>
                                    <li><a href="#">Link 4000</a></li>
                                </ul>
                            </li>
                            </li>
                            <li><a href="#">Link 400</a></li>
                        </ul>
                    </li>
                    <li><a href="#">Link 80</a></li>
                </ul>
            </li>
        </ul>

    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5