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

ReactJS中如何用window.scrollY实现元素滚动至页面垂直中心时淡入

React中基于window.scrollY实现元素滚动至垂直中心时淡入的方案

核心思路是监听页面滚动事件,通过计算元素与视口中心的位置关系,动态控制元素的透明度(或其他样式)来实现淡入效果。以下是具体的实现步骤和代码示例:

实现步骤

  1. 获取元素DOM引用:使用useRef钩子获取目标元素的DOM节点,用于后续计算位置。
  2. 监听滚动事件:在useEffect中添加scroll事件监听,组件卸载时移除监听避免内存泄漏。
  3. 计算位置关系:在滚动回调中,计算视口中心、元素中心的垂直位置,判断元素是否到达视口中心区域。
  4. 动态控制样式:根据位置判断结果,更新状态并触发元素的淡入过渡效果。

完整代码示例

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

const FadeInOnScroll = () => {
  const [isVisible, setIsVisible] = useState(false);
  const targetElement = useRef(null);

  useEffect(() => {
    const checkVisibility = () => {
      if (!targetElement.current) return;

      const viewportHeight = window.innerHeight;
      const elementRect = targetElement.current.getBoundingClientRect();
      // 计算元素的垂直中心位置
      const elementCenterY = elementRect.top + elementRect.height / 2;
      // 视口的垂直中心位置
      const viewportCenterY = viewportHeight / 2;

      // 当元素中心进入视口中心时触发淡入(可根据需求调整触发条件)
      if (elementCenterY <= viewportCenterY && elementCenterY >= 0) {
        setIsVisible(true);
      }
      // 可选:如果需要元素滚出视口中心后重新隐藏,取消下面的注释
      // else if (elementCenterY < 0) {
      //   setIsVisible(false);
      // }
    };

    // 初始加载时检查一次,避免元素初始就在视口中心却不显示
    checkVisibility();
    window.addEventListener('scroll', checkVisibility);

    return () => {
      window.removeEventListener('scroll', checkVisibility);
    };
  }, []);

  return (
    <div
      ref={targetElement}
      style={{
        opacity: isVisible ? 1 : 0,
        transition: 'opacity 0.6s ease-in-out',
        height: '300px',
        margin: '1000px 0', // 让元素初始在视口外,方便测试滚动效果
        backgroundColor: '#e0e0e0',
        padding: '20px',
      }}
    >
      滚动到页面垂直中心时,我会平滑淡入
    </div>
  );
};

export default FadeInOnScroll;

性能优化建议

由于scroll事件触发频率极高,频繁更新状态可能导致性能问题,建议添加防抖处理:

// 防抖函数
const debounce = (func, delay = 50) => {
  let timeoutId;
  return (...args) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func.apply(this, args), delay);
  };
};

// 在useEffect中替换原回调
const debouncedCheck = debounce(checkVisibility);
window.addEventListener('scroll', debouncedCheck);
return () => window.removeEventListener('scroll', debouncedCheck);

扩展动画效果

如果需要更丰富的动画,比如结合位移淡入,可以修改样式:

style={{
  opacity: isVisible ? 1 : 0,
  transform: isVisible ? 'translateY(0)' : 'translateY(20px)',
  transition: 'opacity 0.6s ease-in-out, transform 0.6s ease-in-out',
  // 其他基础样式...
}}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 08:18:31