如何实现汉堡菜单(burger menu)滑动下拉展开效果
你的思路是正确的,动画确实需要添加在topnav-menu容器上,动画不生效的核心原因是当前CSS设置了display: none阻断了transition过渡,调整方法如下:
1. 核心CSS修改
CSS的transition无法对display属性生效,所以首先要移除display相关配置,新增overflow: hidden保证收起时内容不会溢出:
.topnav-menu { width: 300px; transition: all .5s ease; background-color: none; padding: 0; max-height: 0; position: absolute; top: 100%; right: 0; opacity: 0; /* 移除原来的display: none,新增以下属性 */ overflow: hidden; } .open-hamburguer .topnav-menu { opacity: 1; /* 移除原来的display: block,max-height设置为大于菜单最大可能高度的值即可 */ max-height: 500px; }
修改完成后即可实现基础的滑动展开收起效果。
2. 修复点击逻辑缺陷
你当前的JS判断逻辑存在问题:document.querySelector('.outsideOfBurger')只会匹配到第一个带该类的元素(汉堡图标),点击菜单本身内容时会被误判为“点击了菜单外部”导致菜单被意外关闭,修改为以下逻辑即可:
window.addEventListener('click', function(e) { const menu = document.querySelector('.right-nav'); // 判断点击目标是否在菜单/汉堡图标范围内 const isClickInsideMenuArea = e.target.closest('.outsideOfBurger') !== null; if (!isClickInsideMenuArea) { menu.classList.remove('open-hamburguer'); } // 只有点击汉堡图标时才切换菜单状态,点击菜单自身内容不做操作 else if (e.target.closest('.burger-menu') !== null) { menu.classList.toggle('open-hamburguer'); } });
可选优化:动态匹配菜单高度
如果菜单子项数量不固定,希望动画速度和菜单高度严格匹配,可以通过JS动态获取菜单实际高度来控制,修改方案如下:
- 调整CSS配置:
.topnav-menu { width: 300px; /* 单独指定需要过渡的属性,性能更优 */ transition: height .5s ease, opacity .5s ease; background-color: none; padding: 0; /* 把max-height换成height */ height: 0; position: absolute; top: 100%; right: 0; opacity: 0; overflow: hidden; } .open-hamburguer .topnav-menu { opacity: 1; /* 不需要写固定高度,由JS动态赋值 */ }
- 调整JS逻辑:
const menuContainer = document.querySelector('.topnav-menu'); const menuList = document.getElementById('list'); // 提前获取菜单的实际总高度 const menuFullHeight = menuList.scrollHeight + 'px'; window.addEventListener('click', function(e) { const menu = document.querySelector('.right-nav'); const isClickInsideMenuArea = e.target.closest('.outsideOfBurger') !== null; if (!isClickInsideMenuArea) { menu.classList.remove('open-hamburguer'); menuContainer.style.height = 0; } else if (e.target.closest('.burger-menu') !== null) { const isOpen = menu.classList.toggle('open-hamburguer'); menuContainer.style.height = isOpen ? menuFullHeight : 0; } });
内容的提问来源于stack exchange,提问作者Mads Sander Høgstrup
相关产品推荐
相关产品推荐

