马黑黑 发表于 2026-3-4 12:06

两个元素同步滚动演示

<style>
    .artBox { font-size: 20px; margin: 30px auto; max-width: 1200px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; color: #333; }
    .artBox > p { margin: 15px 0; line-height: 1.8; text-align: justify; }
    .artBox blockquote { background: #f9f9f9; border-left: 4px solid #1a73e8; padding: 15px 20px; margin: 20px 0; color: #555; }
    .artBox code { background: #eee; padding: 2px 6px; border-radius: 3px; font-family: 'Consolas', 'Monaco', monospace; font-size: 0.95em; }
    .artBox .mid { text-align: center; }
</style>

<div class="artBox">
    <p><strong>实现滚动同步使用到的属性:</strong></p>
    <blockquote>
          1. Element.scrollTop - 可读写属性,可以获取或设置元素内容从其顶部边缘滚动的像素数。<br>
          2. Element.scrollHeight - 只读属性,是一个元素内容高度,包括由于溢出导致的视图中不可见内容。<br>
          3. Element.clientHeight - 只读属性,对于没有定义 CSS 或者内联布局盒子的元素为 0;否则,它是元素内部的高度(以像素为单位),包含内边距,但不包括边框、外边距和水平滚动条(如果存在)。
    </blockquote>
    <p><strong>实现思路:</strong></p>
    <p>1. 获取滚动元素当前滚动位置(scrollTop)和元素内容高度(scrollHeight - clientHeight)的比例;</p>
    <p>2. 将上述比例值应用于第二个元素,即根据此元素自己的滚动条实际高度计算出 scrollTop 属性值并驱动该值刷新。</p>
    <p>同时应考虑到滚动事件是高发事件,可以设计一个滚动机制以减少CPU消耗,详见代码示例。</p>
    <div class="codebox" data-prev="1">
        &lt;style&gt;
          /* 父元素 */
          .pa {
                margin: 20px auto;
                width: 80vw;
                height: 90vh;
                display: flex;
                gap: 20px;
          }
          /* 子元素 */
          .son {
                width: 50%;
                height: 100%;
                border: 1px solid #ccc;
                overflow: auto;
          }
          /* 孙元素 */
          .grandson {
                height: 300%;
                background: linear-gradient(35deg, tan, beige, snow, beige, tan);
          }
        &lt;/style&gt;
       
        &lt;div class="pa"&gt;
          &lt;div id="son1" class="son"&gt;
                &lt;div class="grandson"&gt;&lt;/div&gt;
          &lt;/div&gt;
          &lt;div id="son2" class="son"&gt;
                &lt;div class="grandson"&gt;&lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
       
        &lt;script&gt;
          let isScrolling = false; // 同步滚动逻辑
       
          son1.addEventListener('scroll', () =&gt; scrolling(son1, son2));
          son2.addEventListener('scroll', () =&gt; scrolling(son2, son1));
       
          /* 滚动函数 */
          function scrolling(el1, el2) {
                if (isScrolling) return;
                isSScrolling = true;
                const per = el1.scrollTop / (el1.scrollHeight - el1.clientHeight);
                el2.scrollTop = per * (el2.scrollHeight - el2.clientHeight);
                setTimeout(() => isScrolling = false, 10);
          }
        &lt;/script&gt;
    </div>
</div>


<script type="module">
    import linenumber from 'https://638183.freep.cn/638183/web/helight/linenumber.js';
    linenumber();
</script>

马黑黑 发表于 2026-3-4 12:09

节流、防抖是滚动事件实际应用中常用到的,本示例没有做防抖功能,节流也是粗糙的,适用于小范围滚动,若是大型项目需要额外设计更为严格的节流防抖机制。

杨帆 发表于 2026-3-4 16:34

有趣~实现了两个滚动区域的同步滚动效果,谢谢马老师经典讲授与精彩示范{:4_180:}

马黑黑 发表于 2026-3-4 17:47

杨帆 发表于 2026-3-4 16:34
有趣~实现了两个滚动区域的同步滚动效果,谢谢马老师经典讲授与精彩示范

{:4_190:}

梦江南 发表于 2026-3-4 18:19

滾动色彩很美,这能用到帖子里吗?{:4_187:}

马黑黑 发表于 2026-3-4 18:27

梦江南 发表于 2026-3-4 18:19
滾动色彩很美,这能用到帖子里吗?

如果觉得有必要

梦江南 发表于 2026-3-4 18:31

马黑黑 发表于 2026-3-4 18:27
如果觉得有必要

滾动色彩做帖子背景蛮赞的。个人觉得是好的。

马黑黑 发表于 2026-3-4 19:01

梦江南 发表于 2026-3-4 18:31
滾动色彩做帖子背景蛮赞的。个人觉得是好的。

好看多看看

梦江南 发表于 2026-3-4 19:05

马黑黑 发表于 2026-3-4 19:01
好看多看看

是哦

红影 发表于 2026-3-4 21:07

两个son显示出来的时候是并列的,还真是同步滚动的。{:4_187:}

马黑黑 发表于 2026-3-5 19:45

红影 发表于 2026-3-4 21:07
两个son显示出来的时候是并列的,还真是同步滚动的。

这时利用两个元素的滚动条位置百分比驱动,应用场景可能会复杂化
页: [1]
查看完整版本: 两个元素同步滚动演示