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

如何在React.js组件中实现所有CSS动画的暂停/播放?

修复全局暂停/播放CSS动画的问题

你的代码存在几个关键问题导致功能失效,以下是具体修复方案:

1. 修正querySelectorAll的选择器语法

document.querySelectorAll仅接受一个包含所有目标选择器的字符串,多选择器需用逗号分隔在同一字符串内,你之前的写法会直接忽略第二个参数。正确写法:

const animations = document.querySelectorAll('.person-name, .background-penny');

2. 正确获取当前动画状态

直接读取animation.style.animationPlayState只能获取元素内联样式中的状态,而你的动画定义在CSS样式表中,初始状态下该值为undefined。应该用getComputedStyle获取页面实际生效的样式:

const computedStyle = window.getComputedStyle(animation);
const running = computedStyle.animationPlayState || 'running';

3. 清理事件监听避免内存泄漏

在useEffect的返回函数中移除点击事件监听,防止组件卸载后残留事件导致内存泄漏:

useEffect(() => {
  const toggleHandler = () => {
    // ... 核心逻辑代码
  };
  const jstoggle = ref.current;
  jstoggle.addEventListener('click', toggleHandler);
  
  // 组件卸载时清理事件
  return () => {
    jstoggle.removeEventListener('click', toggleHandler);
  };
}, []);

4. 优化:用React状态控制按钮文本

添加状态变量跟踪动画状态,让按钮文本动态切换为"PAUSE ANIMATION"或"PLAY ANIMATION",提升用户体验。

完整修复后的Button.js代码

import { useRef, useEffect, useState } from 'react';

function Button() {
  const ref = useRef(null);
  const [isPaused, setIsPaused] = useState(false);

  useEffect(() => {
    const toggleHandler = () => {
      const animations = document.querySelectorAll('.person-name, .background-penny');
      animations.forEach(animation => {
        const computedStyle = window.getComputedStyle(animation);
        const currentState = computedStyle.animationPlayState;
        animation.style.animationPlayState = currentState === 'running' ? 'paused' : 'running';
      });
      setIsPaused(prev => !prev);
    };

    const toggleBtn = ref.current;
    toggleBtn.addEventListener('click', toggleHandler);

    return () => {
      toggleBtn.removeEventListener('click', toggleHandler);
    };
  }, []);

  return (
    <button 
      ref={ref} 
      className="btn" 
      type="button"
    >
      {isPaused ? 'PLAY ANIMATION' : 'PAUSE ANIMATION'}
    </button>
  );
}

export default Button;

可选优化:用全局类控制动画(更符合React思想)

如果不想直接操作DOM元素样式,可以在根元素上添加/移除全局类,通过CSS统一控制动画状态:

1. 添加全局CSS

/* 全局暂停动画类 */
.pause-animations .person-name,
.pause-animations .background-penny {
  animation-play-state: paused !important;
}

2. 修改Button.js和根组件

// Button.js
import { useState } from 'react';

function Button({ togglePause }) {
  const [isPaused, setIsPaused] = useState(false);

  const handleClick = () => {
    togglePause();
    setIsPaused(prev => !prev);
  };

  return (
    <button 
      className="btn" 
      type="button"
      onClick={handleClick}
    >
      {isPaused ? 'PLAY ANIMATION' : 'PAUSE ANIMATION'}
    </button>
  );
}

export default Button;
// App.js示例
import { useState } from 'react';
import Button from './Button';

function App() {
  const [pauseAnimations, setPauseAnimations] = useState(false);

  return (
    <div className={pauseAnimations ? 'pause-animations' : ''}>
      {/* 你的其他组件内容 */}
      <Button togglePause={() => setPauseAnimations(prev => !prev)} />
    </div>
  );
}

这种方式无需直接操作DOM元素,更符合React的状态管理思想,也更易于维护。

内容的提问来源于stack exchange,提问作者chloe.s

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 19:15:54