左侧导航菜单滑出功能实现及点击外部关闭子菜单的方案咨询
左侧导航菜单滑出功能实现及点击外部关闭子菜单的方案咨询
嘿,MikeC,你提的这两个问题用jQuery确实是更省心的选择,我来一步步帮你梳理解决方案,顺便优化下现有代码的交互体验:
一、实现子菜单平滑滑出效果
你当前的代码是直接显示/隐藏子菜单,缺少滑动动画,我们可以通过CSS过渡动画来实现流畅的滑出效果,同时调整布局让子菜单和左侧按钮栏保持并排:
1. 调整HTML结构
把各个子菜单的span元素移到.content-left内部,和.menu-links同级,确保布局上是左右并排的结构:
<section class="quotation-window"> <div class="window-container"> <div class="header-one">header 1</div> <div class="header-two">header 2</div> <div class="content-container"> <div class="content-left"> <div class="menu-links"> <input type="button" value="div1" style="padding: 10px 20px; width: 100%;" /> <input type="button" value="div2" style="padding: 10px 20px; width: 100%;" /> <input type="button" value="div3" style="padding: 10px 20px; width: 100%;" /> </div> <!-- 子菜单移至此处,与按钮栏同级 --> <span id="div1" class="submenu"> <ul> <li><a href="#">Submenu 1</a></li> <li><a href="#">Submenu 2</a></li> <li><a href="#">Submenu 3</a></li> <li><a href="#">Submenu 4</a></li> </ul> </span> <span id="div2" class="submenu"> <ul> <li><a href="#">Submenu 5</a></li> <li><a href="#">Submenu 6</a></li> <li><a href="#">Submenu 7</a></li> <li><a href="#">Submenu 8</a></li> </ul> </span> <span id="div3" class="submenu"> <ul> <li><a href="#">Submenu 9</a></li> <li><a href="#">Submenu 10</a></li> <li><a href="#">Submenu 11</a></li> <li><a href="#">Submenu 12</a></li> </ul> </span> </div> <div class="content-right">right column content</div> </div> </div> </section>
2. 修改CSS样式
添加滑出动画的核心样式,用transform和transition实现平滑过渡:
* {box-sizing: border-box; margin: 0; padding: 0;} html, body {height: 100%;} body {background: #fff; padding: 0; margin: 0; font-family: Myriad-Pro, Arial, 'Varela Round', sans-serif; font-size: 16px;} .quotation-window {display: flex; height: 100%} .window-container {display: flex; flex-direction: row; flex-wrap: wrap; width: 100%;} .header-one {display: flex; width: 100%; background-color: #dbdbdb; padding: 20px 10px;} .header-two {display: flex; width: 100%; background-color: #afafaf; padding: 20px 10px;} .content-container {display: flex; width: 100%; height: 100%} .content-left { display: flex; color: #fff; padding: 0; flex-direction: row; flex-wrap: nowrap; height: 100%; align-items: flex-start; /* 让子菜单与按钮栏顶部对齐 */ } .content-right {display: flex; background-color: #6d6d6d; padding: 20px 10px; flex: 1; /* 占满剩余宽度 */} .menu-links { display: flex; flex-direction: row; flex-wrap: wrap; align-content: flex-start; padding: 20px; background-color: #3f51b5; max-width: 200px; min-width: 200px; } /* 子菜单核心样式 */ .submenu { background-color: #5e69a8; min-width: 200px; padding: 20px; transform: translateX(-100%); /* 默认隐藏在按钮栏后方 */ transition: transform 0.3s ease; /* 平滑过渡动画 */ height: fit-content; /* 与按钮栏高度匹配 */ } .submenu.active { transform: translateX(0); /* 滑出到可视区域 */ } .submenu ul {list-style-type: none;} .submenu ul li {padding: 10px 0;} .submenu ul a {color: #fff; text-decoration: none;} /* 移动端适配调整 */ @media screen and (max-width: 900px) and (min-width: 340px) { .content-left { width: 100%; flex-direction: column; /* 移动端改为垂直布局 */ } .submenu { transform: translateY(-100%); /* 移动端改为向上隐藏 */ width: 100%; } .submenu.active { transform: translateY(0); /* 移动端向下滑出 */ } }
3. 优化jQuery交互逻辑
通过切换类来触发动画,同时处理点击外部关闭的需求:
$(document).ready(function() { // 按钮点击事件 $('.menu-links input').on('click', function(e) { e.stopPropagation(); // 阻止事件冒泡,避免触发document点击事件 // 先隐藏所有子菜单 $('.submenu').removeClass('active'); // 显示当前按钮对应的子菜单 const targetId = '#' + $(this).val(); $(targetId).addClass('active'); }); // 点击页面外部关闭子菜单 $(document).on('click', function(e) { // 判断点击区域是否在左侧导航外 if (!$(e.target).closest('.content-left').length) { $('.submenu').removeClass('active'); } }); });
二、点击外部关闭子菜单的原理说明
上面的代码中,我们通过以下逻辑实现自动关闭:
- 监听
document的全局点击事件,用closest('.content-left')判断点击目标是否属于左侧导航区域(包括按钮和子菜单) - 如果点击的是导航区域外的内容,就移除所有子菜单的
active类,让它们滑回隐藏状态 - 给按钮点击事件添加
e.stopPropagation(),是为了避免点击按钮时,事件冒泡到document,导致刚显示的子菜单立刻被关闭
这样就不需要额外添加关闭按钮,用户点击页面任意非导航区域就能自动关闭子菜单啦。
备注:内容来源于stack exchange,提问作者MikeC
相关产品推荐
相关产品推荐

