用JavaScript精巧地实现文本框的粘贴功能:一次成功的尝试

举报
染念 发表于 2023/11/30 14:33:12 2023/11/30
【摘要】 前言:本文实际是用js移动控制光标的位置!解决了网上没有可靠教程的现状 废话连篇默认情况对一个文本框粘贴,应该会有这样的功能:粘贴文本后,光标不会回到所有文本的最后位置,而是在粘贴的文本之后将选中的文字替换成粘贴的文本但是由于需求,我们需要拦截粘贴的事件,对剪贴板的文字进行过滤,这时候粘贴的功能都得自己实现了,而一旦自己实现,上面2个功能就不见了,我们就需要还原它。面对这样的需求,我们肯定要...

前言:本文实际是用js移动控制光标的位置!解决了网上没有可靠教程的现状

废话连篇

默认情况对一个文本框粘贴,应该会有这样的功能:

  1. 粘贴文本后,光标不会回到所有文本的最后位置,而是在粘贴的文本之后
  2. 将选中的文字替换成粘贴的文本

但是由于需求,我们需要拦截粘贴的事件,对剪贴板的文字进行过滤,这时候粘贴的功能都得自己实现了,而一旦自己实现,上面2个功能就不见了,我们就需要还原它。

面对这样的需求,我们肯定要控制移动光标,可是现在的网上环境真的是惨,千篇一律的没用代码…于是我就发表了这篇文章。

先上代码

    <textarea id="text" style="width: 996px; height: 423px;"></textarea>
    <script>
        // 监听输入框粘贴事件
        document.getElementById('text').addEventListener('paste', function (e) {
            e.preventDefault();
            let clipboardData = e.clipboardData.getData('text');
            // 这里写你对剪贴板的私货
            let tc = document.querySelector("#text");
            tc.focus();
            const start = (tc.value.substring(0,tc.selectionStart)+clipboardData).length;
            if(tc.selectionStart != tc.selectionEnd){
                tc.value = tc.value.substring(0,tc.selectionStart)+clipboardData+tc.value.substring(tc.selectionEnd)
            }else{
                tc.value = tc.value.substring(0,tc.selectionStart)+clipboardData+tc.value.substring(tc.selectionStart); 
            }
            
            // 重新设置光标位置
            tc.selectionEnd =tc.selectionStart = start
        });
    </script>

怎么理解上述两个功能?
第一个解释:
比如说现在文本框有:

染念真的很生气

如果我们现在在真的后面粘贴不要,变成

染念真的不要很生气|

拦截后的光标是在生气后面,但是我们经常使用发现,光标应该出现在不要的后面吧!
就像这样:

染念真的不要|很生气

第2个解释:

染念真的不要很生气

我们全选真的的同时粘贴求你,拦截后会变成

染念真的求你不要很生气|

但默认应该是:

染念求你|不要很生气

代码分析

针对第2个问题,我们应该先要获取默认的光标位置在何处,tc.selectionStart是获取光标开始位置,tc.selectionEnd是获取光标结束位置。
为什么这里我写了一个判断呢?因为默认时候,我们没有选中一块区域,就是把光标人为移动到某个位置(读到这里,光标在位置后面,现在人为移动到就是前面,这个例子可以理解不?),这个时候两个值是相等的。

233|333
^— ^
1-- -4
tc.selectionEnd=4,tc.selectionStart = 4

如果相等,说明就是简单的定位,tc.value = tc.value.substring(0,tc.selectionStart)+clipboardData+tc.value.substring(tc.selectionStart);,tc.value.substring(0,tc.selectionStart)获取光标前的内容,tc.value.substring(tc.selectionStart)是光标后的内容。
如果不相等,说明我们选中了一个区域(光标选中一块区域说明我们选中了一个区域),代码只需要在最后获取光标后的内容这的索引改成tc.selectionEnd

|233333|
^-------- ^
1------ - 7
tc.selectionEnd=7,tc.selectionStart = 1

在获取光标位置之前,我们应该先使用tc.focus();聚焦,使得光标回到文本框的默认位置(最后),这样才能获得位置。
针对第1个问题,我们就要把光标移动到粘贴的文本之后,我们需要计算位置。
获得这个位置,一定要在tc.value重新赋值之前,因为这样的索引都没有改动。
const start = (tc.value.substring(0,tc.selectionStart)+clipboardData).length;这个代码和上面解释重复,很简单,我就不解释了。
最后处理完了,重新设置光标位置,tc.selectionEnd =tc.selectionStart = start,一定让selectionEnd和selectionStart相同,不然选中一个区域了。

如果我们在value重新赋值之后获取(tc.value.substr(0,tc.selectionStart)+clipboardData).length,大家注意到没,我们操作的是tc.value,value已经变了,这里的重新定位光标开始已经没有任何意义了!

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。