当前位置: 首页 > backend >正文

WHAT - 前端开发滚动条场景解析

文章目录

  • 滚动条相关常见问题 + 优化方案总结
    • 1. 性能问题
      • 问题
      • 解决方案
    • 2. 滚动监听失效
      • 问题
      • 解决方案
    • 3. 滚动穿透(Mobile端特有)
      • 问题
      • 解决方案
    • 4. 滚动条样式兼容性问题
      • 问题
      • 解决方案
    • 5. 滚动到底 / 吸顶效果相关问题
      • 问题
      • 解决方案
    • 6. 页面滚动定位问题(如刷新、返回定位)
      • 问题
      • 解决方案
    • 7. 大文件、大数据长列表滚动卡顿
      • 问题
      • 解决方案
    • 8. iOS 特有滚动相关问题
      • 问题
      • 解决方案
      • 具体场景 1. position: fixed 滚动穿透(背景可滚动)
        • 问题描述
        • 原因
        • 解决方案
      • 具体场景 2. 滚动容器“回弹效果”问题(橡皮筋效果)
        • 问题描述
        • 解决方案
      • 具体场景 3. 100vh 高度在 Safari iOS 下不准确
        • 问题描述
        • 解决方案
      • 具体场景 4. 慢速滚动卡顿 or `scrollIntoView` 在 iOS 上表现异常
        • 问题描述
        • 解决方案
  • 总结一下

本期我们将系统地总结一下前端开发中与**滚动条(滚动行为)**相关的问题和常见优化方案。

滚动条相关常见问题 + 优化方案总结

1. 性能问题

问题

  • 滚动时触发大量 scroll 事件,频繁执行回调,导致卡顿、掉帧
  • 尤其是回调中有 DOM 查询、布局重排(reflow/repaint)操作时,影响更大。

解决方案

  • 节流(throttle)或 requestAnimationFrame 处理 scroll 事件,减少执行频率。如:requestAnimationFrame 或 lodash 的 throttle 节流函数。
  • 避免在滚动事件里频繁操作 DOM,改成只读操作,比如只记录滚动位置,批量更新。
  • 对滚动范围很大的内容使用 虚拟列表(virtual scroll / windowing),如:react-windowreact-virtualizedvue-virtual-scroll-list

2. 滚动监听失效

问题

  • 内容动态变化后,scroll 事件监听不到,比如新增大量 DOM,或外部容器尺寸变化。
  • 特定元素使用了 overflow: auto,监听错了元素(比如监听 window 而不是正确的容器)。

解决方案

  • 确保监听正确的滚动容器,不是所有情况都是 window
  • 动态内容变化时,考虑重新绑定或更新监听逻辑。
  • 使用 ResizeObserver 监听元素尺寸变化,结合更新滚动逻辑。

ResizeObserver 是浏览器原生提供的一个非常实用的 API,它可以用来监听 DOM 元素尺寸变化(而不是窗口大小变化),这在滚动场景中非常有用。

具体来说,在某些场景中,元素内容变化引起的尺寸变化不会自动触发滚动相关逻辑,比如:

  • 动态加载内容导致滚动区域变大,但没有触发你监听的 scroll 事件。
  • 无限滚动(下拉加载更多)中,内容快速填充但不够触发滚动,需要判断是否还要加载更多。
  • 元素缩放、隐藏、调整布局时,你需要实时重新计算滚动范围或滚动条。
  1. 场景一:动态内容撑开容器,自动触发“是否到底部”的判断
const container = document.querySelector('.scroll-container');const resizeObserver = new ResizeObserver(() => {const isBottom = container!.scrollHeight <= container!.clientHeight + container!.scrollTop;if (isBottom) {// 自动加载更多数据loadMore();}
});resizeObserver.observe(container!);
  1. 场景二:滚动容器尺寸改变时,重新计算滚动条、偏移量等逻辑
//例如表格容器宽度变化导致横向滚动条显示/隐藏,更新滚动位置
const observer = new ResizeObserver(entries => {for (const entry of entries) {const el = entry.target;// 重新计算滚动相关布局,比如:updateScrollOffset(el.scrollTop);}
});observer.observe(document.querySelector('.my-scroll-box')!);

注意事项:

  • ResizeObserver 的触发是异步的,回调在布局完成之后执行。
  • 使用完要调用 observer.disconnect() 断开监听,防止内存泄露。
  • 如果你只需要监听窗口大小变化,请用 window.onresize

3. 滚动穿透(Mobile端特有)

问题

  • 在移动端,弹出层(如弹窗、抽屉)打开后,背景内容还能滚动。
  • 会造成体验不佳,比如弹窗内容和背景一起滑动。

解决方案

  • 弹出层打开时,禁用 body 滚动,如:
    body {overflow: hidden;
    }
    
  • 更细粒度控制,防止 “穿透”,使用:
    • touchmove 事件监听,preventDefault()
    • 第三方库:如 body-scroll-lock
  • 有时要注意弹出层本身可以滚动(比如内容很多时),要细分处理。

4. 滚动条样式兼容性问题

问题

  • 原生滚动条在不同浏览器(特别是 Windows Chrome / Mac Safari)样式不一致。
  • 移动端常常隐藏原生滚动条,自定义滚动条样式。
  • 隐藏滚动条但保留滚动功能兼容难。

解决方案

  • 使用标准 CSS 隐藏滚动条但允许滚动:
    /* 隐藏滚动条,仍可滚动 */
    .scrollable 
http://www.xdnf.cn/news/3086.html

相关文章:

  • scratch代码——游戏开发 【弹簧与反弹】
  • Java-jwt4.4.0版本使用
  • 特殊权限管理
  • Linux命令使用记录(自用)
  • LS-Linux-004 误删 Python 和 yum、dnf 后的恢复步骤
  • neurips2025_latex
  • Python3(16) 函数
  • 安卓基础(无障碍点击)
  • 通用人工智能(AGI)的技术演进
  • 新人销售如何找精准客户?
  • 语言特性的发展与应用:从基础到前沿的全面解析
  • 25年第八本【活着】
  • 基于STM32、HAL库的DS28E25安全验证及加密芯片驱动程序设计
  • 一些常用的深度学习可视化平台:TensorBoard、Weights Biases (wandb)、VisualDL
  • C++ 原子操作的内存序(memory ordering)
  • ptpx常用操作
  • 企业选择IT技术人员外包能解决哪些问题
  • 【Axure高保真原型】动态地图路线
  • 三维引擎HOOPS SDK适配Linux ARM64,对国产工业软件意味着什么?
  • 深入剖析扩散模型对镜子反射理解局限:MirrorVerse 项目改进数据集与训练方法以提升反射处理表现的研究
  • 基于STM32、HAL库的ATECC608A安全验证及加密芯片驱动程序设计
  • LDO中反向二极管作用
  • 【每天一个知识点】GPU(图形处理单元)和CPU(中央处理单元)
  • Java—— 四道算法经典题
  • jthread是否可以完全取代thread?
  • 共享货源系统,多商户独立站助力行业资源整合
  • 掌握 Linux 中 SELinux 的强制访问控制机制和 iptables、 firewalld 两种防火墙以及他们的使用方法
  • 双系统,bios默认设置启动ubuntu+ubuntu改启动grub设置
  • 学习在暑假避免躺平和内卷(马井堂)
  • FlexNoC随手记