js 实现滚动条同步效果

2024-08-05

一、效果演示

一九八四年 庄稼还没收割完。女儿躺在我怀里 睡得那么甜。今晚的露天电影 没时间去看。妻子提醒我 修修缝纫机的踏板。明天我要去 邻居家再借点钱。孩子哭了一整天啊 闹着要吃饼干。蓝色的涤卡上衣 痛往心里钻。蹲在池塘边上 给了自己两拳。这是我父亲日记里的文字。这是他的青春 留下 留下来的散文诗。
一九八四年 庄稼还没收割完。女儿躺在我怀里 睡得那么甜。今晚的露天电影 没时间去看。妻子提醒我 修修缝纫机的踏板。明天我要去 邻居家再借点钱。孩子哭了一整天啊 闹着要吃饼干。蓝色的涤卡上衣 痛往心里钻。蹲在池塘边上 给了自己两拳。这是我父亲日记里的文字。这是他的青春 留下 留下来的散文诗。

二、代码实现

1.

原理:分别给左右两个 div 绑定 scroll 事件,当其中一个 div 滚动时,将当前 div 滚动条位置 scrollTop 设置为另一个 div 滚动条位置,以此实现滚动条位置同步效果。

<style> 
    .wrapper {
        display: flex;
        gap: 20px;
    }

    .left, .right {
        width: 100px;
        height: 200px;
        border: 1px solid #ccc;
        overflow: auto;
    }
</style>

<div class="wrapper">
    <div class="left">
        一九八四年 庄稼还没收割完。女儿躺在我怀里 睡得那么甜。今晚的露天电影 没时间去看。妻子提醒我 修修缝纫机的踏板。明天我要去 邻居家再借点钱。孩子哭了一整天啊 闹着要吃饼干。蓝色的涤卡上衣 痛往心里钻。蹲在池塘边上 给了自己两拳。这是我父亲日记里的文字。这是他的青春 留下 留下来的散文诗。
    </div>
    <div class="right">
        一九八四年 庄稼还没收割完。女儿躺在我怀里 睡得那么甜。今晚的露天电影 没时间去看。妻子提醒我 修修缝纫机的踏板。明天我要去 邻居家再借点钱。孩子哭了一整天啊 闹着要吃饼干。蓝色的涤卡上衣 痛往心里钻。蹲在池塘边上 给了自己两拳。这是我父亲日记里的文字。这是他的青春 留下 留下来的散文诗。
    </div>
</div>

<script>
    const leftEl = document.querySelector('.left')
    const rightEl = document.querySelector('.right')

    leftEl.addEventListener('scroll', function () {
        rightEl.scrollTop = leftEl.scrollTop
    })

    rightEl.addEventListener('scroll', function () {
        leftEl.scrollTop = rightEl.scrollTop
    })
</script>

有些文章里提到这种滚动同步有卡顿,理由是左边 div 滚动时,会修改右边 div 的 scrollTop 值,这个修改会立刻触发右边 div 的 scroll 事件,导致左边 div 的 scrollTop 值被修改,又会触发左边 div 的 scroll 事件,造成循环,导致同步效果不顺滑。

本文测试同步效果还是蛮顺滑的,不清楚是浏览器厂商对 scroll 事件做了优化,还是说不同操作系统,亦或是不同浏览器会有这种滚动条同步卡顿问题,本文也提供一种规避左右 div 循环触发 scroll 事件的例子。

原理:当鼠标移入左边 div 时,左边 div 添加 scroll 事件,右边 div 移除 scroll 事件。当鼠标移入右边 div 时,右边 div 添加 scroll 事件,左边 div 移除 scroll 事件。

<style> 
    .wrapper {
        display: flex;
        gap: 20px;
    }

    .left, .right {
        width: 100px;
        height: 200px;
        border: 1px solid #ccc;
        overflow: auto;
    }
</style>

<div class="wrapper">
    <div class="left">
        一九八四年 庄稼还没收割完。女儿躺在我怀里 睡得那么甜。今晚的露天电影 没时间去看。妻子提醒我 修修缝纫机的踏板。明天我要去 邻居家再借点钱。孩子哭了一整天啊 闹着要吃饼干。蓝色的涤卡上衣 痛往心里钻。蹲在池塘边上 给了自己两拳。这是我父亲日记里的文字。这是他的青春 留下 留下来的散文诗。
    </div>
    <div class="right">
        一九八四年 庄稼还没收割完。女儿躺在我怀里 睡得那么甜。今晚的露天电影 没时间去看。妻子提醒我 修修缝纫机的踏板。明天我要去 邻居家再借点钱。孩子哭了一整天啊 闹着要吃饼干。蓝色的涤卡上衣 痛往心里钻。蹲在池塘边上 给了自己两拳。这是我父亲日记里的文字。这是他的青春 留下 留下来的散文诗。
    </div>
</div>

<script>
    const leftEl = document.querySelector('.left')
    const rightEl = document.querySelector('.right')

    const onLeftScroll = () => {
        rightEl.scrollTop = leftEl.scrollTop
    }
    
    const onRightScroll = () => {
        leftEl.scrollTop = rightEl.scrollTop
    }
    
    leftEl.addEventListener('mouseenter', () => {
        rightEl.removeEventListener('scroll', onRightScroll)
        leftEl.addEventListener('scroll', onLeftScroll)
    })

    rightEl.addEventListener('mouseenter', () => {
        leftEl.removeEventListener('scroll', onLeftScroll)
        rightEl.addEventListener('scroll', onRightScroll)
    })
</script>

返回首页

本文总阅读量  次
总访问量: 
总访客量: