js实现多滚动条同步滚动(两个以上)

2,171 阅读3分钟

实现两个滚动条滚动条左边滚动右边跟随滚动

    // 获取左右盒子元素
    var left = document.querySelector("yourBoxLeft"); 
    var right = document.querySelector("yourBoxRight");
    // 绑定左边的滚动事件
    function bindEventLeft() {
        left.addEventListener('scroll', leftScroll)
    }
    // 左边滚动时候,右边同步
    function leftScroll() {
        var a = left.scrollTop;
        //竖向滚动条同步
        right.scrollTop = a;
        //横向滚动条同步
        right.scrollLeft = left.scrollLeft;
    }
    left.addEventListener('mouseover', bindEventLeft)

实现两个滚动条滚动左边或者右边时两边都能同步滚动

    // 获取左右盒子元素
    var left = document.querySelector("yourBoxLeft"); 
    var right = document.querySelector("yourBoxRight");
    // 绑定左边的滚动事件
    function bindEventLeft() {
        left.addEventListener('scroll', leftScroll)
    }
    // 绑定右边的滚动事件
    function bindEventRight() {
        right.addEventListener('scroll', rightScroll)
    }
    // 左边滚动时候,右边同步
    function leftScroll() {
        var a = left.scrollTop;
        //竖向滚动条同步
        right.scrollTop = a;
        //横向滚动条同步
        right.scrollLeft = left.scrollLeft;
    }
    // 右边滚动时候,左边同步
    function rightScroll() {
        var a = right.scrollTop;
        left.scrollTop = a
        left.scrollLeft = right.scrollLeft
    }
    left.addEventListener('mouseover', bindEventLeft)
    right.addEventListener('mouseover', bindEventRight)

问题

上面已经可以实现两个滚动条同步滚动了,但是由于两边都绑定了滚动事件,在滚动一边时会不停的相互触发另一边的滚动事件会造成滚动困难或者滚动卡顿。

让滚动丝滑起来

思路: 在一边滚动时使用removeEventListener()解除掉另一边的滚动事件。

    // 获取左右盒子元素
    var left = document.querySelector("yourBoxLeft"); 
    var right = document.querySelector("yourBoxRight");
    // 绑定左边的滚动事件
    function bindEventLeft() {
        removeEventRight() //关键点:绑定左边滚动事件时先解绑右边滚动事件
        left.addEventListener('scroll', leftScroll)
    }
    // 绑定右边的滚动事件
    function bindEventRight() {
        removeEventLeft() //关键点:绑定右边滚动事件时先解绑左边滚动事件
        right.addEventListener('scroll', rightScroll)
    }
    //   解绑左边的滚动事件
    function removeEventLeft() {
        left.removeEventListener('scroll', leftScroll)
    }
    //   解绑右边的滚动事件
    function removeEventRight() {
        right.removeEventListener('scroll', rightScroll)
    }
    // 左边滚动时候,右边同步
    function leftScroll() {
        var a = left.scrollTop;
        //竖向滚动条同步
        right.scrollTop = a;
        //横向滚动条同步
        right.scrollLeft = left.scrollLeft;
    }
    // 右边滚动时候,左边同步
    function rightScroll() {
        var a = right.scrollTop;
        left.scrollTop = a
        left.scrollLeft = right.scrollLeft
    }
    left.addEventListener('mouseover', bindEventLeft)
    right.addEventListener('mouseover', bindEventRight)

三个滚动条同步滚动

最笨的方法(画个瓢)

    // 获取元素
    var l = document.querySelector("yourBox1");
    var r = document.querySelector("yourBox2");
    var q = document.querySelector("yourBox3");
    //********************************绑定事件 */
    function bindEventLeft() {
        removeEventRight() //关键点-先解绑
        removeEventq()
        l.addEventListener('scroll', leftScroll)
    }

    function bindEventRight() {
        removeEventLeft() //关键点-先解绑
        removeEventq()
        r.addEventListener('scroll', rightScroll)
    }

    function bindEventq() {
        removeEventLeft() //关键点-先解绑
        removeEventRight()
        q.addEventListener('scroll', qScroll)
    }
    //************************************解绑事件 */
    //   解绑左边的滚动事件
    function removeEventLeft() {
        l.removeEventListener('scroll', leftScroll)
    }
    //   解绑右边的滚动事件
    function removeEventRight() {
        r.removeEventListener('scroll', rightScroll)
    }
    //   解绑事件
    function removeEventq() {
        q.removeEventListener('scroll', qScroll)
    }
    //***********************************滚动同步 */
    // 左边滚动时候,右边同步
    function leftScroll() {
        r.scrollTop = l.scrollTop;
        q.scrollTop = l.scrollTop;
        r.scrollLeft = l.scrollLeft;
        q.scrollLeft = l.scrollLeft;
    }
    // 右边滚动时候,左边同步
    function rightScroll() {
        l.scrollTop = r.scrollTop;
        q.scrollTop = r.scrollTop;
        l.scrollLeft = r.scrollLeft;
        q.scrollLeft = r.scrollLeft;
    }

    function qScroll() {
        l.scrollTop = q.scrollTop;
        r.scrollTop = q.scrollTop;
        l.scrollLeft = q.scrollLeft;
        r.scrollLeft = q.scrollLeft;
    }
    l.addEventListener('mouseover', bindEventLeft)
    r.addEventListener('mouseover', bindEventRight)
    q.addEventListener('mouseover', bindEventq)

如果需要更多的滚动条同步滚动或者需要把动态渲染出来的盒子进行滚动条同步滚动我们可能会累死

为了防止我们被累死(下面是一种思路,抛转引玉)

我们需要去批量获取元素,批量绑定滚动事件,批量去解绑除自身以外盒子的滚动事件
当需要根据接口数据动态渲染出多个盒子并要求他们可以同步滚动时可以在拼接html时给每个盒子一个name属性,如name=name0,name=name1...方便我们去批量选择元素。

// 滚动条同步滚动
function sameSroll(num){
    //获取所有元素
    var o = [];
    for(var i=0;i<=num-1;i++){
        var query = "div[name=name"+i+"]";
        o.push(query);
    }
    //绑定事件
    function bindEvent(e){
        var index = e.currentTarget.id;
        removeEvent(index);//绑定事件前先解绑事件,否则同步滚动过程中,会不停相互触发滚动事件,造成卡顿或滚动困难。
        document.querySelector(o[index]).addEventListener('scroll', allScroll)
    }
    //解绑事件
    function removeEvent(i){
        o.forEach((item,index)=>{
            if(i!=index){
                document.querySelector(item).removeEventListener("scroll",allScroll)
            }
        })
    }
    //同步滚动
    function allScroll(e){
        var i = e.currentTarget.id
        o.forEach((item,index)=>{
            if(i!=index){
                //竖向滚动
                document.querySelector(item).scrollTop=document.querySelector(o[i]).scrollTop;
                //横向滚动
                document.querySelector(item).scrollLeft=document.querySelector(o[i]).scrollLeft;
            }
        })
    }
    o.forEach((item,index)=>{
        //根据mouseover事件,为当前盒子绑定事件
        document.querySelector(item).addEventListener('mouseover', bindEvent)
    })
}