div同步滚动的方式

先来放图看效果

滚动

在一切开始前我们先来测试原生的js实现的方法

1.新建一个test.html文件

要求在html中创建两个div,同等固定高度的,并随意填充任意的text,p div等大量超出div的高度。


2.需求分析

我们的目的是尽量左边滚动右边同步滚动,而右边滚动左边却不滚动。代码如下。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>原生滚动方式</title>
</head>
<body>
    <div id="app">
    <div class="scroll-left" id="left">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>
    <div class="scroll-right" id="right">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>
</div>
</body>

<script>
//左div绑定滚动事件
    let left=document.getElementById('left');
    let right=document.getElementById("right");
    left.onscroll=(e)=>{
        console.log("滚动事件",e.target.scrollTop);   //scrollTop即为元素滚动的高度’‘
        console.log("打印此时右边的滚动高度",right.scrollTop);
        //同步,即吧左边的scrollTop赋值给右边的scrollTop
        /******* !!!!!!!!!!!!!!!!!!!!!!!!******/
        right.scrollTop=e.target.scrollTop;
    }
</script>

<style scoped>
    #app{
        display: flex;
    }
    .scroll-left,
    .scroll-right{
        width:40%;
        height:600px;
    }
    .scroll-left{
        background-color: antiquewhite;
        overflow: auto;
    }
    .scroll-right{
        background-color: #c3faff;
        overflow: auto;
    }
    .item{
        height:200px;
        width:90%;
        margin-bottom: 50px;
    }
    .scroll-left .item{
        background-color: brown;
    }
    .scroll-right .item{
        background-color: coral;
    }
</style>
</html>

原生javascript

从代码上,我只是把左右两边的滚动条打开overflowauto,接着在js中对左边的div绑定scroll事件,事件中把左侧的垂直滚动的距离scrollTop直接给右侧的垂直滚动距离,而右侧不绑定任何事件,这样,滚动右侧的滚动条可实现右侧的同步,而右侧的滚动对左侧没有任何的影响

3.vue.js的设计方案

明确了原生的js实现方式,我们来用vue.js复现并美化一下。

vue.js初步了解

vuescroll 美化滚动条

思路是一样的,唯一不同的是采用vuescroll的回调函数来控制。

请查看handle-scroll事件scrollTo API

参考代码如下

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue 双开div同步滚动测试</title>
</head>

<body>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vuescroll"></script>
    <div id="app">
        <vue-scroll :ops="left" class="left-scroll" @handle-scroll="leftScroll" ref="v-left">
            <div class="left" ref="left">
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
            </div>
        </vue-scroll class="right-scroll" @handle-scroll="rightScroll" ref="v-right">
        <vue-scroll>
            <div class="right" ref="right">
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
                <div class="item-block"></div>
            </div>
        </vue-scroll>
    </div>
</body>

<script>
    const vs=new Vue();
    const vm = new Vue({
        el: '#app',
        data() {
            return {
                msg: 'hello world!',
                //left是左侧的vuescroll参数
                left:{
                    vuescroll: {
                        mode:'native',
                        //locking:true
                    },
                    scrollPanel: {
                        speed:400,
                        //scrollingX:false,
                        //scrollingY:true
                        scrollingX:false
                    },
                    rail: {
                        keepShow:true,
                        opacity:0.7,
                        background:'rgb(229, 229, 229)'
                    },
                    bar: {
                        keepShow:true
                    }
                },
                leftCH:0
            }
        },
        created() {},
        //注意 refs在挂载后才生效,故下面的代码放在mounted中
        mounted() {
            let rightScrollTop = this.$refs["right"].scrollTop
            let that = this;  //因为下面函数的this不再指向此vue实例
            this.$refs["left"].onscroll = function (e) {
                // console.log(this.scrollTop)
                that.$refs["right"].scrollTop = this.scrollTop
                //console.log(that.$refs["right"].scrollTop)
            }
            vs.$on("left-change",(e,arg)=>{
                //console.log("事件监听器",e,that.$children[1])
            });

        },
        methods:{
            //vuecroll的回调函数,实现同步
            leftScroll(vertical,horizontal,nativeEvent){
                //console.log(vertital,horizontal,nativeEvent)  全部打印
                //console.log(vertital)  //部分打印,高度变化
               // console.log(this.$refs['v-right'])//打印得到undefined
                let that=this;
                let change=vertical.scrollTop-this.leftCH;
                this.leftCH=vertical.scrollTop;
                console.log(change)
                this.$children[1].scrollTo({
                    y:vertical.scrollTop
                },0)
                vs.$emit("left-change",vertical.scrollTop)
            },
            rightScroll(vertital,horizontal,nativeEvent){
                
            }
        },
    });
</script>

<style scoped>

    #app {
        height: 550px;
       /* overflow: hidden;*/
    }

    #app {
        display: flex;
    }

    .left,
    .right {
        height: fit-content;
       
    }

    .left {
        /*width: 40%;*/
        background-color: aquamarine;
        /*overflow: auto;*/
    }

    .right {
        /*width: 40%;*/
        background-color: red;
        /*overflow: auto;*/
    }

    .left .item-block {
        height: 300px;
        width: 80%;
        background-color: yellow;
        margin-top: 20px;
    }

    .right .item-block {
        height: 300px;
        width: 80%;
        background-color: rgb(0, 225, 255);
        margin-top: 20px
    }
    .left-scroll .__rail-is-horizontal{
        display: none!important;
    }
</style>

</html>

关键部分已经写好注释了,具体的API方法和回调懒得说,说明自行参看附上的链接。

如有问题欢迎下方留言或者邮箱联系zero@zerotower.xyz

Good Bye ~

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值