【React】可视区检测与平滑滚动实现

元素可视区检测和滚动定位是高频需求(如表单校验提示、锚点导航、异常元素定位等)

javascript 复制代码
// useRef 是 React 中用于获取 DOM 元素的核心 Hook
// 返回的 ref 对象在组件生命周期内保持不变
// 通过 targetRef.current 可直接访问绑定的 DOM 节点。
const targetRef = useRef(null)

// 判断元素是否在是窗口内
  const isInviteEleView = useCallback((element) => {
    if (!element) return false

    // 视窗尺寸获取
    const viewportHeight = window.innerHeight || document.documentElement.clientHeight
    const viewportWidth = window.innerWidth || document.documentElement.clientWidth

    // 四个条件同时满足 → 元素完全在视窗内
    return (
      // 元素顶部不超出视窗上边界
      element.top >= 0 &&
      // 元素左侧不超出视窗左边界
      element.left >= 0 &&
      // 元素底部不超出视窗下边界
      element.bottom <= viewportHeight &&
      // 元素右侧不超出视窗右边界
      element.right <= viewportWidth
    )
}, [])

useEffect(() => {
    // getBoundingClientRect() 获取目标元素的位置信息
    const currentEle = targetRef.current?.getBoundingClientRect()

    if (....) {
      // 判断元素是否在视窗内(滚动到元素位置)
      if (!isInviteEleView(currentEle)) {
        targetRef.current?.scrollIntoView({
          // 滚动方式:'auto'/'smooth'
          behavior: 'smooth',
          // 垂直方向对齐方式:'start'/'center'/'end'/'nearest'
          block: 'center',
          // 水平方向对齐方式:'start'/'center'/'end'/'nearest'
          inline: 'nearest',
        })
      }
    }
}, [isInviteEleView])

<>
    <div ref={targetRef}>test</div>
</>

应用场景扩展

该代码模式可适配多种前端场景:

  1. 表单校验:表单提交时,若某输入框校验失败,自动滚动到该输入框并高亮;
  2. 长列表导航:侧边栏锚点点击,滚动到对应内容区并确保内容在视窗居中;
  3. 异常提示:页面加载 / 操作异常时,滚动到异常元素位置,提升用户体验;
  4. 懒加载优化:结合可视区判断,实现图片 / 组件的懒加载(仅当元素进入视窗时加载)。
相关推荐
福兮说10 小时前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
\光辉岁月/10 小时前
5.java-数组
java·开发语言
Java后端的Ai之路10 小时前
Python进阶探索29_eval内置函数
开发语言·python·探索·eval·内置函数
谢亮_vipxieliang11 小时前
Spring 事务失效的常见场景
java·开发语言·数据库·spring boot
时间的拾荒人11 小时前
Qt 多线程详解:从 QThread 到实战
开发语言·qt·面试
郑州光合科技余经理11 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
2601_9620715711 小时前
类变量和全局变量的生命周期有什么区别?
java·开发语言·jvm
Wang's Blog11 小时前
Java 项目实战: 外卖平台优化-前后端分离开发模式与工程拆分
java·开发语言
小呆呆66612 小时前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
凤城老人12 小时前
从 PyQt6 到 Electron:给 Edge TTS 做一个“多角色配音机“的踩坑手记
javascript·typescript·electron