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

实现带延迟的<li>旋转/缩放过渡动画失败,求技术排查

解决圆形展开按钮中<li>元素无过渡动画的问题

看起来你遇到的核心问题是jQuery的delay()方法无法延迟toggleClass()的执行——这是因为delay()默认只对jQuery的动画队列方法(比如animate()、fadeIn()这类)生效,而类切换不属于动画队列,所以你写的延迟根本没起作用,所有<li>的pill类是瞬间加上的,自然看不到过渡动画。

修复步骤

  1. 替换delay()为setTimeout()
    我们需要用原生的setTimeout()来控制每个<li>的类切换时机,这样才能真正实现递增延迟的效果。同时要区分鼠标移入和移出的状态,避免移出时的动画逻辑混乱。

修改后的JS代码:

$('.top-left').hover(
  // 鼠标移入时:逐个添加类,实现递增动画
  function() {
    $(this).addClass("pill");
    $('.top-left ul').addClass("pill");
    $('.top-left img').addClass("pill");
    $('.top-left ul li').each(function(i, elem) {
      setTimeout(() => {
        $(elem).addClass("pill");
      }, i * 150); // 把延迟调小到150ms,动画更连贯,原800ms过于生硬
    });
  },
  // 鼠标移出时:反向逐个移除类,动画更自然
  function() {
    const liCount = $('.top-left ul li').length;
    $('.top-left ul li').each(function(i, elem) {
      setTimeout(() => {
        $(elem).removeClass("pill");
      }, (liCount - 1 - i) * 150);
    });
    // 最后移除父元素的类,确保收缩动画同步完成
    setTimeout(() => {
      $(this).removeClass("pill");
      $('.top-left ul').removeClass("pill");
      $('.top-left img').removeClass("pill");
    }, liCount * 150);
  }
);
  1. 优化CSS过渡的兼容性
    确保<li>的初始状态和pill状态的transform属性完全对应,同时把<ul>的display: none替换为opacity + visibility,让列表的显示/隐藏也有平滑过渡:
.top-left ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  font-size: 35px;
  margin-left: 0;
  opacity: 0; /* 替换display: none */
  visibility: hidden; /* 防止未显示时占空间 */
  transform: translate(20px, -46px);
  transition: opacity 0.25s ease;
}
.top-left ul.pill {
  opacity: 1;
  visibility: visible;
}
.top-left ul li {
  cursor: pointer;
  padding-right: 10px;
  float: left;
  transition: all 0.25s cubic-bezier(0, 1.4, 1, 1); /* 明确过渡所有属性 */
  transform: scale(0.01,0.01) rotate(-30deg) translate(43px, 0px);
}
.top-left ul li.pill {
  transform: scale(1,1) rotate(0deg) translate(43px, 0);
}

为什么原来的代码不行?

  • $(elem).delay(i * 800).toggleClass("pill"):delay()只会延迟队列里的动画方法,toggleClass是立即执行的,所以所有<li>同时切换类,没有过渡序列。
  • 用setTimeout()可以精准控制每个<li>的类切换时间,让CSS的过渡动画逐个触发,实现你想要的递增延迟效果。

完整运行代码

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="top-left">
  <img src="http://placehold.it/100x100" alt="Close icon">
  <ul>
    <li value='1'><i class="icon-twitter-sign">🐦</i></li>
    <li value='2'><i class="icon-twitter-sign">🐦</i></li>
    <li value='3'><i class="icon-instagram">📸</i></li>
  </ul>
</div>

<style>
.top-left {
  width: 55px;
  height: 55px;
  border-radius: 55px;
  transition: width ease 0.3s;
  margin-top: 15px;
  background: #4d4d4d;
  border: 4px solid #333;
  cursor: pointer;
  overflow: hidden; /* 防止<li>溢出圆形容器 */
}
.top-left.pill {
  width: 207px;
}
.top-left img {
  margin: auto;
  width: 40px;
  display: table;
  margin: 6px auto 10px;
  transition: all 0.25s cubic-bezier(0, 1.4, 1, 1);
}
.top-left img.pill {
  margin-left: 15px;
  transform: rotate(90deg);
}
.top-left ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  font-size: 35px;
  margin-left: 0;
  opacity: 0;
  visibility: hidden;
  transform: translate(20px, -46px);
  transition: opacity 0.25s ease;
}
.top-left ul.pill {
  opacity: 1;
  visibility: visible;
}
.top-left ul li {
  cursor: pointer;
  padding-right: 10px;
  float: left;
  color: #ccc;
  transition: all 0.25s cubic-bezier(0, 1.4, 1, 1);
  transform: scale(0.01,0.01) rotate(-30deg) translate(43px, 0px);
}
.top-left ul li.pill {
  transform: scale(1,1) rotate(0deg) translate(43px, 0);
}
.top-left ul li.pill:hover {
  color: #fff;
}
</style>

<script>
$('.top-left').hover(
  function() {
    $(this).addClass("pill");
    $('.top-left ul').addClass("pill");
    $('.top-left img').addClass("pill");
    $('.top-left ul li').each(function(i, elem) {
      setTimeout(() => {
        $(elem).addClass("pill");
      }, i * 150);
    });
  },
  function() {
    const liCount = $('.top-left ul li').length;
    $('.top-left ul li').each(function(i, elem) {
      setTimeout(() => {
        $(elem).removeClass("pill");
      }, (liCount - 1 - i) * 150);
    });
    setTimeout(() => {
      $(this).removeClass("pill");
      $('.top-left ul').removeClass("pill");
      $('.top-left img').removeClass("pill");
    }, liCount * 150);
  }
);
</script>

这样修改后,你就能看到每个<li>按照递增延迟完成旋转和缩放的过渡动画,同时按钮的展开/收缩也会更流畅~

内容的提问来源于stack exchange,提问作者blue

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:30:47