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

如何在React+Tailwind项目中用IntersectionObserver实现滚动动画组件

实现滚动触发的左滑淡入动画并封装可复用React组件

问题分析

原代码存在几个关键问题:

  • React中直接操作DOM(document.querySelectorAll、classList)不符合组件化范式,易引发渲染不一致
  • 类名错误(添加/移除.opacity-100时多了前缀点)
  • 仅实现透明度变化,缺少左滑位移动画
  • 组件无法复用,section内容硬编码

解决方案步骤

1. 定义动画样式(基于Tailwind CSS)

先添加动画过渡的自定义样式,实现从左侧滑入+淡入的效果:

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer utilities {
  .slide-in-left {
    transition: all 0.6s ease-out;
  }
  .hidden-state {
    opacity: 0;
    transform: translateX(-20px);
  }
  .visible-state {
    opacity: 1;
    transform: translateX(0);
  }
}

2. 封装可复用的动画Section组件

创建AnimatedSection组件,通过ref监听元素交集状态,内部处理动画逻辑:

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

const AnimatedSection = ({ children, className = '' }) => {
  const sectionRef = useRef(null);

  useEffect(() => {
    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach(entry => {
          if (entry.isIntersecting) {
            entry.target.classList.add('visible-state');
            entry.target.classList.remove('hidden-state');
          } else {
            entry.target.classList.add('hidden-state');
            entry.target.classList.remove('visible-state');
          }
        });
      },
      { threshold: 0.1 } // 元素进入视口10%时触发动画
    );

    const currentRef = sectionRef.current;
    if (currentRef) {
      observer.observe(currentRef);
    }

    return () => {
      if (currentRef) {
        observer.unobserve(currentRef);
      }
    };
  }, []);

  return (
    <section
      ref={sectionRef}
      className={`slide-in-left hidden-state ${className}`}
    >
      {children}
    </section>
  );
};

export default AnimatedSection;

3. 在父组件中复用AnimatedSection

修改TestAnimation组件,使用封装好的AnimatedSection替代硬编码的section:

import React from 'react';
import AnimatedSection from './AnimatedSection';

const TestAnimation = () => {
  return (
    <div className='m-0 bg-slate-900 p-0 text-white'>
      <AnimatedSection className='grid min-h-screen place-items-center content-center'>
        <h1>Test</h1>
      </AnimatedSection>
      <AnimatedSection className='grid min-h-screen place-items-center content-center'>
        <h2>This is first page</h2>
        <p>
          Lorem ipsum dolor, sit amet consectetur adipisicing elit. Autem modi voluptatem est iste a commodi
          nesciunt saepe quisquam id dignissimos odit, repellat asperiores laboriosam quibusdam expedita
          itaque blanditiis eos pariatur.
        </p>
      </AnimatedSection>
      <AnimatedSection className='grid min-h-screen place-items-center content-center'>
        <h2>This is third page</h2>
        <p>
          Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consectetur veniam sint illo quas beatae,
          eum omnis, deleniti error, eveniet praesentium fugiat quia quod? Maxime, placeat reiciendis ab
          debitis exercitationem nemo. Laborum perspiciatis eum architecto laboriosam, necessitatibus
          voluptatibus cupiditate accusantium corrupti placeat mollitia omnis tenetur! Incidunt fugiat
          possimus quod, quidem itaque ducimus, perspiciatis eligendi, commodi voluptate cupiditate nihil
          corrupti soluta maxime.
        </p>
      </AnimatedSection>
      <AnimatedSection className='grid min-h-screen place-items-center content-center'>
        <h2>this is Fourth page</h2>
        <p className='text-center'>
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Quos similique harum, officiis facere odit
          adipisci maxime obcaecati placeat, quibusdam totam magni eaque? Dicta id commodi saepe dignissimos
          quam unde eaque.
        </p>
      </AnimatedSection>
    </div>
  );
};

export default TestAnimation;

关键说明

  • React范式兼容:使用useRef获取DOM元素,useEffect处理IntersectionObserver的生命周期,避免直接操作全局DOM
  • 动画效果:通过transform: translateX实现左滑,配合opacity实现淡入,transition控制动画时长和缓动效果
  • 复用性:AnimatedSection通过children接收任意内容,className传递自定义样式,适配不同场景
  • 触发阈值:threshold: 0.1设置元素进入视口10%时触发动画,可根据需求调整

内容的提问来源于stack exchange,提问作者antonkornilov-ua

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 01:21:06