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

Web 实现多组件同步滚动

前言

在日常业务开发中,我们有时会遇到多个组件需要同步滚动的场景;例如在某个页面中存在多个相关的数据表格,用户在滚动其中一个表格时,其他表格也同步滚动保证数据行的对齐;这个功能在数据看板、仪表盘等多种场景下都很常见。

实现这种功能并非难事,主要思路为监听各个组件的滚动事件,当某个组件主动滚动后将自身的滚动状态同步给其他组件;但这种实现方式背后存在严重的隐患:当某个组件接收到来自其他组件的主动滚动信息,并据此对自身的滚动状态加以同步后,该组件会被动触发滚动事件,并将自身的滚动信息传递给主动滚动组件;在这种情况下,极易造成死循环,并在页面上的表现为组件不停“抽搐”。

思路

要解决这个问题,我们需要理清思路;我们假设当前存在 A 和 B 两个可滚动组件需要进行信息同步,按照上述解决方案编写代码后,整个事件的触发流程如下:

A 主动滚动 -> B 同步 A 的滚动信息 -> A 同步 B 的滚动信息 -> A 主动滚动 -> 无限循环

而理想状态下整个事件的触发流程如下:

A 主动滚动 -> B 同步 A 的滚动信息 -> A 主动滚动 -> B 同步 A 的滚动信息

两者中的区别在于,理想状态下被动滚动的组件不会反复触发滚动事件造成主动组件的滚动。要解决这个问题,我们可以通过在滚动事件中对引起滚动的来源进行区分,从而判断是否要进行滚动信息同步。

Coding

首先编写组件对应的滚动处理程序,当某个组件主动滚动时,scrollPart 为空,则将 scrollPart 设置为当前组件名称;而主动滚动的组件再次触发滚动时,将会同步滚动信息给其他组件,此时其他组件会被动触发滚动事件;由于此前已将 scrollPart 设置为主动滚动事件的组件名称,因此其他组件被动触发滚动事件后会将 scrollPart 置空。

在这种情况下,即使主动滚动的组件被其他组件触发被动滚动,也不会再次进行同步。

type ScrollPart = "compA" | "compB";
let scrollPart: ScrollPart; // 触发原始滚动的组件名称// 根据组件名称生成组件滚动事件的回调处理程序
const scrollCallbackFactory = (key: ScrollPart) => {return () => {if (!scrollPart) {scrollPart = key;} else if (scrollPart === key) {syncScrollState();} else {scrollPart = undefined;}}
}

接下来需要添加事件监听程序和事件信息同步程序。

const compA = document.querySelector("#compA");
const compB = document.querySelector("#compB");compA.addEventListener("scroll", scrollCallbackFactory("compA"));
compA.addEventListener("scroll", scrollCallbackFactory("compB"));function syncScrollState() {switch (scrollPart) {case "compA":compB.scrollTop = compA.scrollTop;break;case "compB":compA.scrollTop = compB.scrollTop;break;}
}

这种处理组件同步的方法是可扩展的,支持横向、纵向滚动以及多个组件滚动,只需给对应组件添加事件监听,并在 syncScrollState 函数里按照对应的组件同步滚动信息即可。

附件:https://gitee.com/ZhongBangKeJi/CRMEB

http://www.jsqmd.com/news/345989/

相关文章:

  • 10 年经典不褪色!美明定时助手 4M 免费无广告 多任务定时超实用
  • 智能健康监测手环设计
  • 为何云卓科技C11吊舱能适配多种规格载具?
  • 智能浇花系统的设计
  • AI智能识别人脸情绪项目
  • 亲测好用! 降AIGC软件 千笔·降AI率助手 VS 学术猹,继续教育首选
  • 【开题答辩全过程】以 基于Python的茶叶销售数据可视化分析系统设计实现为例,包含答辩的问题和答案
  • 剖析黑龙江汽车噪音治理,各品牌价格与服务对比排名 - 工业品牌热点
  • leetcode 904. Fruit Into Baskets 水果成篮
  • 【开题答辩全过程】以 基于PHP的发热病人管理平台的设计与实现为例,包含答辩的问题和答案
  • 设计稿还原为什么总是出问题?一次设计转代码的实测分享
  • 2026年深圳婚姻纠纷律师联系电话推荐:可靠律师资源与沟通建议 - 品牌推荐
  • 2026年深圳离婚律师联系电话推荐:五大优选律师介绍 - 品牌推荐
  • 脚本双雄:Bash vs Python,谁才是你开发的“灵魂伴侣” ?
  • 2026年深圳婚姻纠纷律师联系电话推荐:专业律师资源全览 - 品牌推荐
  • 写作压力小了!10个降AIGC平台测评:专科生如何选才能降AI率过关?
  • 2026年成都靠谱的制袋机公司盘点,华裕托盘袋制袋机实力大揭秘 - myqiye
  • 了解迪拜房产相关资讯,时代出国成功案例多不多? - 工业设备
  • 两级电力市场环境下计及风险的省间交易商最优购电模型
  • 2026年探讨高性价比的聚氨酯筛板工厂,为您节省成本 - 工业推荐榜
  • 2026年深圳离婚纠纷律师联系电话推荐:专业团队联系指引 - 品牌推荐
  • docker拉取代理脚本
  • 靠谱的医药车间净化板漆面修复公司有哪些 - 工业品网
  • 千匠网络领跑S2B电商软件排名:重塑供应链赋能新范式 - 圆圆小达人
  • 全场景视频技术赋能千行百业:点播直播视频会议平台EasyDSS全面构建视频新生态
  • 【异常】使用 Set.of 构建集合抛出 IllegalArgumentException 异常排查
  • 基于MATLAB的通信中继仿真实现(AFDF策略对比)
  • 2026年高性价比的道路护栏工厂盘点,途亮护栏实力凸显 - 工业品牌热点
  • 2026年舟山长乔海洋国际旅游度假区推荐项目,科普与餐饮质量怎么样 - mypinpai
  • 【Python教程13】-数据库支持