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

如何用JavaScript动态设置CSS动画关键帧实现加购动效?

实现商品加入购物车的动画效果需求

我想在商品页面实现一个动画效果:当用户点击“加入购物车”时,商品图片会动画式地移动并缩小至导航栏的购物车图标处。现有示例代码如下:

HTML代码

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="test"></div>

CSS代码

.test {
  position   : fixed;
  top        : 200px;
  left       : 600px;
  background : red;
  width      : 200px;
  height     : 300px;
}
@keyframes toCart {
  25% {
    top    : 850px;
    left   : 550px;
    width  : 200px;
    height : 300px;
  }
  100% {
    top    : 100px;
    left   : 1100px;
    width  : 0;
    height : 0
  }
}
.animateTest {
  animation : toCart 2s;
}

JavaScript代码

$('div.test').on('animationend', (e) => {
  $(e.target).remove();
})
// 用户点击触发
$('div.test').addClass('animateTest');

目前的难点是用户视口存在差异,我已经能用JS获取购物车图标的位置:

whereIsCart = $('#cartIcon').offset()

希望能把@keyframes的100%关键帧动态设置为购物车的位置:

100% {
  top    : whereIsCart.top;
  left   : whereIsCart.left;
  width  : 0;
  height : 0
}

请问该如何实现?或者有没有更优的方案达成这一目标?


解决方案

下面提供几种实用的实现方案,适配不同场景需求:

方案一:动态创建CSS关键帧

通过JS动态生成包含购物车实时位置的@keyframes规则,完美适配不同视口的位置差异:

// 绑定加入购物车按钮点击事件
$('.add-to-cart').click(function() {
  // 获取购物图标的实时位置
  const cartOffset = $('#cartIcon').offset();
  // 克隆当前商品的图片(避免影响原元素)
  const $productImg = $(this).closest('.product').find('img').clone();
  
  // 设置克隆元素的初始定位(和原图片位置一致)
  const productOffset = $productImg.offset();
  $productImg.css({
    position: 'fixed',
    top: productOffset.top + 'px',
    left: productOffset.left + 'px',
    width: $productImg.width() + 'px',
    height: $productImg.height() + 'px',
    zIndex: 9999,
    pointerEvents: 'none' // 防止动画元素遮挡页面交互
  }).appendTo('body');

  // 动态生成关键帧样式
  const keyframes = `
    @keyframes toCart {
      100% {
        top: ${cartOffset.top}px;
        left: ${cartOffset.left}px;
        width: 0;
        height: 0;
        opacity: 0;
      }
    }
  `;
  // 创建style标签并插入到页面头部
  const style = document.createElement('style');
  style.innerHTML = keyframes;
  document.head.appendChild(style);

  // 给克隆元素添加动画类触发动画
  $productImg.addClass('animate-to-cart');

  // 动画结束后清理元素和动态样式
  $productImg.on('animationend', function() {
    $(this).remove();
    style.remove();
  });
});

配套的基础CSS:

.animate-to-cart {
  animation: toCart 1.5s ease-in-out forwards;
}

方案二:CSS变量+JS赋值(更高效)

利用CSS变量存储动态位置,无需每次创建新的关键帧,性能更优:

先写基础CSS

@keyframes toCart {
  100% {
    top: var(--cart-top);
    left: var(--cart-left);
    width: 0;
    height: 0;
    opacity: 0;
  }
}

.animate-to-cart {
  animation: toCart 1.5s ease-in-out forwards;
  position: fixed;
  z-index: 9999;
  pointer-events: none;
}

再写JS逻辑

$('.add-to-cart').click(function() {
  const cartOffset = $('#cartIcon').offset();
  const $productImg = $(this).closest('.product').find('img').clone();
  const productOffset = $productImg.offset();

  // 设置初始位置并给元素赋值CSS变量
  $productImg.css({
    top: productOffset.top + 'px',
    left: productOffset.left + 'px',
    width: $productImg.width() + 'px',
    height: $productImg.height() + 'px',
    '--cart-top': cartOffset.top + 'px',
    '--cart-left': cartOffset.left + 'px'
  }).appendTo('body').addClass('animate-to-cart');

  // 动画结束后移除元素
  $productImg.on('animationend', function() {
    $(this).remove();
  });
});

方案三:Web Animations API(纯JS控制,更灵活)

直接用JS的Web Animations API控制动画,不需要依赖CSS关键帧,适合需要复杂动态逻辑的场景:

$('.add-to-cart').click(function() {
  const cartOffset = $('#cartIcon').offset();
  const $productImg = $(this).closest('.product').find('img').clone();
  const productOffset = $productImg.offset();
  const imgWidth = $productImg.width();
  const imgHeight = $productImg.height();

  // 设置克隆元素的初始样式
  $productImg.css({
    position: 'fixed',
    top: productOffset.top + 'px',
    left: productOffset.left + 'px',
    width: imgWidth + 'px',
    height: imgHeight + 'px',
    zIndex: 9999,
    pointerEvents: 'none'
  }).appendTo('body');

  // 使用Web Animations API执行动画
  $productImg[0].animate([
    // 初始状态
    { transform: 'translate(0, 0)', opacity: 1, width: imgWidth + 'px', height: imgHeight + 'px' },
    // 结束状态:移动到购物车位置并缩小消失
    { 
      transform: `translate(${cartOffset.left - productOffset.left}px, ${cartOffset.top - productOffset.top}px)`,
      opacity: 0,
      width: '0px',
      height: '0px'
    }
  ], {
    duration: 1500, // 动画时长1.5秒
    easing: 'ease-in-out' // 缓动效果
  }).onfinish = function() {
    // 动画结束后移除元素
    $productImg.remove();
  };
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 15:05:33