博主信息
博文 77
粉丝 0
评论 0
访问量 35071
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
Web 实现多组件同步滚动
い独霸天下う
原创
130人浏览过

前言

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

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

思路

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

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

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

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

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

Coding

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

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

  1. type ScrollPart = "compA" | "compB";
  2. let scrollPart: ScrollPart; // 触发原始滚动的组件名称
  3. // 根据组件名称生成组件滚动事件的回调处理程序
  4. const scrollCallbackFactory = (key: ScrollPart) => {
  5. return () => {
  6. if (!scrollPart) {
  7. scrollPart = key;
  8. } else if (scrollPart === key) {
  9. syncScrollState();
  10. } else {
  11. scrollPart = undefined;
  12. }
  13. }
  14. }

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

  1. const compA = document.querySelector("#compA");
  2. const compB = document.querySelector("#compB");
  3. compA.addEventListener("scroll", scrollCallbackFactory("compA"));
  4. compA.addEventListener("scroll", scrollCallbackFactory("compB"));
  5. function syncScrollState() {
  6. switch (scrollPart) {
  7. case "compA":
  8. compB.scrollTop = compA.scrollTop;
  9. break;
  10. case "compB":
  11. compA.scrollTop = compB.scrollTop;
  12. break;
  13. }
  14. }

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

附件:https://www.php.cn/xiazai/code/7303

本博文版权归博主所有,转载请注明地址!如有侵权、违法,请联系admin@php.cn举报处理!
全部评论 文明上网理性发言,请遵守新闻评论服务协议
0条评论
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号

  • 登录PHP中文网,和优秀的人一起学习!
    全站2000+教程免费学