js 实现菜单下滑
实现菜单下滑效果
使用JavaScript实现菜单下滑效果通常需要结合CSS过渡或动画。以下是几种常见实现方式:
基础CSS过渡实现
通过添加/移除类名触发CSS过渡效果:
.menu {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-out;
}
.menu.open {
max-height: 500px; /* 大于实际内容高度即可 */
}
const menu = document.querySelector('.menu');
const toggleBtn = document.querySelector('.toggle-btn');
toggleBtn.addEventListener('click', () => {
menu.classList.toggle('open');
});
动态计算高度实现
精确计算内容高度实现平滑过渡:
function toggleMenu() {
const menu = document.querySelector('.menu');
if (menu.style.maxHeight) {
menu.style.maxHeight = null;
} else {
menu.style.maxHeight = menu.scrollHeight + 'px';
}
}
使用Web Animation API
现代浏览器支持的动画API:
const menu = document.querySelector('.menu');
function animateMenu() {
const isOpen = menu.classList.contains('open');
const animation = menu.animate([
{ maxHeight: '0px', opacity: 0 },
{ maxHeight: `${menu.scrollHeight}px`, opacity: 1 }
], {
duration: 300,
easing: 'ease-in-out'
});
animation.onfinish = () => {
menu.classList.toggle('open', !isOpen);
};
}
带缓动函数的实现
添加更复杂的缓动效果:
function slideMenu(menu, duration = 300) {
const start = performance.now();
const startHeight = menu.offsetHeight;
const endHeight = menu.classList.contains('open') ? 0 : menu.scrollHeight;
function step(timestamp) {
const progress = Math.min((timestamp - start) / duration, 1);
const easeProgress = easeOutQuad(progress);
menu.style.height = startHeight + (endHeight - startHeight) * easeProgress + 'px';
if (progress < 1) {
requestAnimationFrame(step);
} else {
menu.classList.toggle('open');
menu.style.height = '';
}
}
requestAnimationFrame(step);
}
function easeOutQuad(t) {
return t * (2 - t);
}
注意事项
- 移动端兼容性需测试transform性能
- 内容动态变化时需要重新计算高度
- 过渡结束后移除内联样式保持CSS灵活性
- 考虑添加ARIA属性增强可访问性
以上方法可根据具体需求选择或组合使用,CSS过渡方案性能最佳,JavaScript方案控制更精细。







