重复触发点击事件后侧边导航动画延迟持续递增问题求助
解决侧边导航重复操作后动画延迟递增的问题
嘿,我一眼就看出问题出在哪啦!你每次点击汉堡菜单打开侧边栏的时候,都会给遮罩层(overflow_wrapper_overlay)重新绑定一次click事件。重复操作6-7次后,这个遮罩上就堆积了好多个点击事件处理器——等你点击遮罩关闭时,所有绑定的事件都会同时触发,相当于浏览器要连续执行好几次关闭动画,队列越堆越长,延迟自然就越来越高了。
解决方案:避免重复绑定事件
咱们把遮罩的点击事件绑定逻辑移到汉堡菜单的点击事件外面,只绑定一次就够了。另外,用一个变量跟踪侧边栏的状态,比通过position().left判断更可靠(毕竟动画没完成时,位置可能还没更新)。
修改后的JavaScript代码如下:
/***** sidenav script *****/ // 用变量跟踪侧边栏状态,避免依赖位置判断 var isSidenavOpen = false; // 提前缓存DOM元素,不用每次点击都重新查找 var sidenav = $('div.sidenav'); var overflow_wrapper = $('.overflow-wrapper'); var overflow_wrapper_overlay = $('.overflow-wrapper .overflow-wrapper-overlay'); // 遮罩点击事件只绑定一次,不会重复堆积 overflow_wrapper_overlay.on('click', function() { sidenav.animate({ 'left': -250 }, 200); overflow_wrapper.animate({ 'left': 0 }, 200); setTimeout(function() { overflow_wrapper_overlay.addClass('d-none'); $('html, body').css({ 'overflow': 'unset' }); isSidenavOpen = false; }, 200); }); $('.sidenav-burger-menu').on('click', function() { if (!isSidenavOpen) { $('html, body').css({ 'overflow': 'hidden' }); sidenav.animate({ 'left': 0 }, 200); overflow_wrapper.animate({ 'left': 250 }, 200); overflow_wrapper_overlay.removeClass('d-none'); // z-index可以直接写在CSS里,不用动态设置 overflow_wrapper_overlay.css('z-index', '99'); isSidenavOpen = true; } });
进阶优化:用CSS过渡替代jQuery动画
如果想让动画更流畅,还可以用CSS过渡(transition)代替jQuery的animate方法,性能更好也更易维护。
首先修改SCSS,给侧边栏和内容容器添加过渡效果:
/***** sidenav styles *****/ .sidenav { height: 100vh; width: 250px; position: fixed; z-index: 3; top: 0; left: -250px; background-color: #111; overflow-x: hidden; // 添加过渡动画 transition: left 0.2s ease; } .overflow-wrapper { width: 100%; height: 100%; overflow: hidden; position: relative; left: 0; // 添加过渡动画 transition: left 0.2s ease; .overflow-wrapper-overlay { position: absolute; background: rgba(0, 0, 0, .7); height: 100%; width: 100%; z-index: 99; // 直接在这里设置z-index,不用JS动态改 } .main-content { height: 100vh; } } // 新增两个类,控制侧边栏和容器的位置 .sidenav-open { left: 0; } .content-shifted { left: 250px; }
然后简化JavaScript代码,通过添加/移除类来控制动画:
/***** sidenav script *****/ var isSidenavOpen = false; var sidenav = $('div.sidenav'); var overflow_wrapper = $('.overflow-wrapper'); var overflow_wrapper_overlay = $('.overflow-wrapper .overflow-wrapper-overlay'); overflow_wrapper_overlay.on('click', function() { sidenav.removeClass('sidenav-open'); overflow_wrapper.removeClass('content-shifted'); setTimeout(function() { overflow_wrapper_overlay.addClass('d-none'); $('html, body').css({ 'overflow': 'unset' }); isSidenavOpen = false; }, 200); }); $('.sidenav-burger-menu').on('click', function() { if (!isSidenavOpen) { $('html, body').css({ 'overflow': 'hidden' }); sidenav.addClass('sidenav-open'); overflow_wrapper.addClass('content-shifted'); overflow_wrapper_overlay.removeClass('d-none'); isSidenavOpen = true; } });
这样修改后,不管你操作多少次,都不会出现事件堆积的问题,动画也会一直保持流畅~
内容的提问来源于stack exchange,提问作者HarshvardhanSharma
相关产品推荐
相关产品推荐

