html中两个textarea同步滚动

html中两个textarea同步滚动

两个textarea同步滚动的问题

关于两个textarea之间同步滚动的事件绑定很容易写出来,但是之前发现两个textarea直接简单地相互绑定scroll的话,滚动起来会非常地卡顿,无法正常使用。所以这里主要是解决这个问题。
在这里插入图片描述

分析

    直接绑定scroll时,当elem1设定了elem2的scrollTop时,触发了elem2的scroll事件,然后设定了elem1的scrollTop,进而重复触发了elem1的scroll事件。 我个人把这种现象叫做事件回响。
    之前有尝试过每次scroll事件发生时把另一个元素的scroll事件去掉,scroll后再重新绑定上,但是发现不起作用。 后来猜测是因为移除事件不是即时的,需要一定的时间,所以在设定scroll值时另一个元素的scroll事件还在,回响现象依然发生。
    后来采用的是以下方法:在元素1滚动时,把元素2的滚动事件解除,且在100毫秒的倒计时后重新绑定上。 个人觉得这种方式性能很好, 因为滚动事件大多数情况下是连续触发,解除元素2的事件后可以完全消除回响现象, 提高性能。 且在100毫秒的时间内,一般人做不到马上切换到另一个元素。
    实际同步滚动效果很斯滑, 和单独滚动一个textarea没什么区别。

代码

主要的js代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <meta title="Scroll Test"/>
    <style type="text/css" rel="stylesheet">
        *{margin:0; padding: 0}
        body{display: flex; padding: 10px;justify-content: space-around;}
        #text1,#text2{width: calc(50% - 10px); height: calc(100vh - 20px); resize: none;padding: 2px; box-sizing: border-box;}
    </style>
</head>
<body>

    <textarea id="text1"></textarea>
    <textarea id="text2"></textarea>

    <script type="text/javascript">
        window.onload = function(){
            let text1 = document.getElementById('text1');
            let text2 = document.getElementById('text2');
            // 绑定同步滚动
            bindScroll(text1, text2);
        }

        /**
         * 绑定同步滚动
         * elem1  滚动元素1
         * elem2  滚动元素2
         */
        function bindScroll(elem1, elem2){
            let timeout1;
            let timeout2;
            let elem1Func = function(e){
                // 如果elem2上已有滚动事件,先解绑
                !timeout1 && elem2.removeEventListener('scroll', elem2Func);
                elem2.scrollTo(e.target.scrollLeft, e.target.scrollTop);

                // 清空倒计时
                timeout1 && clearTimeout(timeout1);
                // 滚动后,100毫秒倒计时后重新绑定滚动事件
                timeout1 = setTimeout(function(){elem2.addEventListener('scroll', elem2Func); timeout1 = undefined;}, 100);
            };

            let elem2Func = function(e){
                !timeout2 && elem1.removeEventListener('scroll', elem1Func);
                elem1.scrollTo(e.target.scrollLeft, e.target.scrollTop);

                timeout2 && clearTimeout(timeout2);
                timeout2 = setTimeout(function(){elem1.addEventListener('scroll', elem1Func); timeout2 = undefined;}, 100);
            };

            elem1.addEventListener('scroll', elem1Func);
            elem2.addEventListener('scroll', elem2Func);
        }

    </script>
</body>
</html>
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值