You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重复触发点击事件后侧边导航动画延迟持续递增问题求助

解决侧边导航重复操作后动画延迟递增的问题

嘿,我一眼就看出问题出在哪啦!你每次点击汉堡菜单打开侧边栏的时候,都会给遮罩层(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:58:02