jQuery slideUp 动画队列堆积问题

解决鼠标快速触发导致动画滞后反复执行的问题

问题

使用 jQuery 的 slideUp/slideDown 动画时,当鼠标快速连续触发,动画会不断加入队列,导致滞后反复执行。

// 问题代码
$('.box').hover(
  function() {
    $(this).find('.content').slideDown();
  },
  function() {
    $(this).find('.content').slideUp();
  }
);

快速移入移出时,动画会持续抖动执行。

解答

方案一:使用 stop() 方法

// stop() 停止当前动画,立即开始新动画
$('.box').hover(
  function() {
    $(this).find('.content').stop().slideDown();
  },
  function() {
    $(this).find('.content').stop().slideUp();
  }
);

方案二:使用 stop(true, true)

// stop(true, true) - 清除队列并跳到动画结束状态
$('.box').hover(
  function() {
    $(this).find('.content').stop(true, true).slideDown();
  },
  function() {
    $(this).find('.content').stop(true, true).slideUp();
  }
);

方案三:使用 finish()

// finish() - 停止当前动画,清除队列,直接到达最终状态
$('.box').hover(
  function() {
    $(this).find('.content').finish().slideDown();
  },
  function() {
    $(this).find('.content').finish().slideUp();
  }
);

方案四:使用 slideToggle 简化

$('.box').hover(function() {
  $(this).find('.content').stop(true, true).slideToggle();
});

完整示例

<!DOCTYPE html>
<html>
<head>
  <style>
    .box {
      width: 200px;
      background: #f0f0f0;
      margin: 20px;
    }
    .title {
      padding: 10px;
      background: #333;
      color: #fff;
      cursor: pointer;
    }
    .content {
      display: none;
      padding: 20px;
    }
  </style>
</head>
<body>
  <div class="box">
    <div class="title">鼠标悬停</div>
    <div class="content">展开的内容区域</div>
  </div>

  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <script>
    $('.box').hover(
      function() {
        // stop(true, true) 确保动画不堆积
        $(this).find('.content').stop(true, true).slideDown(300);
      },
      function() {
        $(this).find('.content').stop(true, true).slideUp(300);
      }
    );
  </script>
</body>
</html>

stop() 参数说明

.stop(clearQueue, jumpToEnd)

// clearQueue: 是否清除动画队列,默认 false
// jumpToEnd: 是否立即完成当前动画,默认 false

.stop()           // 停止当前动画,队列中下一个动画立即开始
.stop(true)       // 清除队列,停在当前位置
.stop(true, true) // 清除队列,跳到当前动画结束状态

关键点

  • stop() 在动画前调用,阻止队列堆积
  • stop(true, true) 清除队列并跳到结束状态,效果最干净
  • finish()stop(true, true) 的简写,jQuery 1.9+ 可用
  • 根据需求选择:stop() 保留过渡感,stop(true, true) 响应更快