textarea实现输入账号回车添加;删除时选中整个账号的效果

这篇博客介绍了如何使用Vue自定义指令实现在textarea中实现输入账号时,回车键自动添加分号';',以及在删除时选中整个账号的功能。内容涉及了不同浏览器环境下获取和设置textarea选中范围的方法,并提供了相关参考资料。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

选中textarea特定范围的内容(该textarea已被focused):

IE9以上浏览器:

textarea.focus();
textarea.setSelectionRange(rangeData.start, rangeData.end, [optional] selectionDirection)

IE9及以下:

textarea.focus();
var range = textarea.createTextRange(); 
range.moveStart("character", rangeData.startDev); // 偏移量
range.moveEnd("character", rangeData.endDev);  
range.collapse(false);  //强制光标移动到结束位置
range.select();  //选择范围内文本

获取textarea选中范围的起始位置及内容:
IE9以上浏览器:

textarea.focus();
rangeData.start = textarea.selectionStart;
rangeData.end = textarea.selectionEnd;
rangeData.text = (rangeData.start != rangeData.end) ? textarea.value.substring(rangeData.start, rangeData.end) : "";

IE9及以下:

textarea.focus();
var i, 
	oS = document.selection.createRange(),
	// 为了使 oR 与 oS 在同一等级上比较 Don't: oR = textarea.createTextRange()
	oR = document.body.createTextRange();
// 移动文本范围以便范围的开始和结束位置能够完全包含给定元素的文本
// 移动body的范围,使其范围的开始和结束位置包含textarea的整个文本
oR.moveToElementText(textarea); 
rangeData.text = oS.text;
// 比较textarea的文本开始位置与当前选中范围的开始位置,不断先去移动开始位置,直至到达文本开始位置
for (i = 0; oR.compareEndPoints('StartToStart', oS) < 0 && oS.moveStart("character", -1) !== 0; i++) {
  // IE下回车也会占到一个字符
  if (textarea.value.charAt(i) == '\r') {
      i++;
  }
}
rangeData.start = i;
rangeData.end = rangeData.text.length + rangeData.start;

向textarea指定位置添加文本:

// 当textarea选中文本时,添加的文本替换当前选中文本
// textarea未选中时,文本插入到光标位置(start与end相同)
this.set(textarea, rangeData); // 选中textarea特定范围的内容

IE9以上浏览器:

oValue = textarea.value;
nValue = oValue.substring(0, rangeData.start) + text + oValue.substring(rangeData.end);
nStart = nEnd = rangeData.start + text.length;
st = textarea.scrollTop;
textarea.value = nValue;
// 保持textarea滚动位置不改变
if (textarea.scrollTop != st) {
    textarea.scrollTop = st;
}
// 光标指向该位置
textarea.setSelectionRange(nStart, nEnd);

IE9及以下:

// 获取当前选中文本
sR = document.selection.createRange();
// 替换文本
sR.text = text;
// 将sR的End位置不变,起始位置与End位置合并
sR.setEndPoint('StartToEnd', sR);
// 光标指向该位置
sR.select();

实现回车时在名称后自动添加 「;」,删除时选中;前的整个名称的效果:

// 注册keydown事件
textarea.addEventListener('keydown', function(e) {
	// 	enter回车
	if(e.keyCode == 13) {...}
	// backspace删除
	if(e.keyCode == 8) {...}
})

// enter回车处理 e.keyCode == 13
e.preventDefault();
rangeData = cursorPosition.get(this);
//此时未选中文本,获取光标位置
if (rangeData.start == rangeData.end) {
    if (0 == rangeData.end) return;
    if (str.charAt(rangeData.end - 1) != ";"){  //光标前一个字符不是;
        cursorPosition.add(this, rangeData, ";"); //在光标位置插入;
    }
}

// backspace删除 e.keyCode == 8
//获取选择文本及光标位置
rangeData = cursorPosition.get(this);
if (rangeData.start == rangeData.end) {  //此时未选中文本,获取光标位置
    if (0 == rangeData.end) return;      //光标在最开头
    // 光标前的字符是;
    if (str.charAt(rangeData.end - 1) == ";"){  
    	// 第一个字符是;
        if (1 == rangeData.end) return; 
		e.preventDefault();
		// 找到前一个;的位置
        var start = str.lastIndexOf(";", rangeData.end - 2),
        	end = rangeData.end;
       	setData = {
			start: start + 1,
			end: end,
			startDev: start - rangeData.start + 1,
			endDev: 0
		}
		// 选中该账号
		cursorPosition.set(textarea, setData);
     }
}

vue自定义指令实现如下:IE9部分无效

var textareaEvent = {
    bind(el, binding, vnode) {
        var cursorPosition = {
            get: function(textarea) { //获取选中内容
                var rangeData = { text: "", start: 0, end: 0 };
				textarea.focus();
                if (textarea.setSelectionRange) { //W3C
                    rangeData.start = textarea.selectionStart;
                    rangeData.end = textarea.selectionEnd;
                    rangeData.text = (rangeData.start != rangeData.end) ? textarea.value.substring(rangeData.start, rangeData.end) : "";
                } else if (document.selection) { //IE
                    var i, oS = document.selection.createRange(),
                        // 为了使 oR 与 oS 在同一等级上比较 Don't: oR = textarea.createTextRange()
                        oR = document.body.createTextRange();
                    // 移动文本范围以便范围的开始和结束位置能够完全包含给定元素的文本
					// 移动body的范围,使其范围的开始和结束位置包含textarea的整个文本
                    oR.moveToElementText(textarea);
                    rangeData.text = oS.text;
                    // 比较textarea的文本开始位置与当前选中范围的开始位置,不断先去移动开始位置,直至到达文本开始位置
                    for (i = 0; oR.compareEndPoints('StartToStart', oS) < 0 && oS.moveStart("character", -1) !== 0; i++) {
                        // IE下回车也会占到一个字符
                        if (textarea.value.charAt(i) == '\r') {
                            i++;
                        }
                    }
                    rangeData.start = i;
                    rangeData.end = rangeData.text.length + rangeData.start;
                }

                return rangeData;
            },
            set: function(textarea, rangeData) {
                var oR;
                if (!rangeData) {
                    alert("You must get cursor position first.")
                }
                textarea.focus();
                if (textarea.setSelectionRange) { // W3C
                    textarea.setSelectionRange(rangeData.start, rangeData.end);
                } else if (textarea.createTextRange) { // IE
                    oR = textarea.createTextRange();
                    range.moveStart("character", rangeData.startDev); // 偏移量
					range.moveEnd("character", rangeData.endDev);  
					range.collapse(false);  //强制光标移动到结束位置
					range.select();  //选择范围内文本
                }
            },
            add: function(textarea, rangeData, text) { //插入文本
                var oValue, nValue, sR, nStart, nEnd, st;
                this.set(textarea, rangeData);

                if (textarea.setSelectionRange) { // W3C
                    oValue = textarea.value;
                    nValue = oValue.substring(0, rangeData.start) + text + oValue.substring(rangeData.end);
                    nStart = nEnd = rangeData.start + text.length;
                    st = textarea.scrollTop;
                    textarea.value = nValue;
                    // 保持textarea滚动位置不改变
                    if (textarea.scrollTop != st) {
                        textarea.scrollTop = st;
                    }
                    // 光标指向该位置
                    textarea.setSelectionRange(nStart, nEnd);
                } else if (textarea.createTextRange) { // IE
                	// 获取当前选中文本
                    sR = document.selection.createRange();
                    // 替换文本
                    sR.text = text;
                    // 将sR的End位置不变,起始位置与End位置合并
                    sR.setEndPoint('StartToEnd', sR);
                    // 光标指向该位置
                    sR.select();
                }
            }
        };

        function textareaEvent(e) {
            var str = this.value,
                rangeData = {};

            if (e.keyCode == 13) { //enter
                e.preventDefault();
                rangeData = cursorPosition.get(this);
                if (rangeData.start == rangeData.end) { //此时未选中文本,获取光标位置
                    if (0 == rangeData.end) return; //光标在最开头
                    if (str.charAt(rangeData.end - 1) != ";") { //光标前一个字符不是;
                        cursorPosition.add(this, rangeData, ";"); //在光标位置插入;
                    }
                }
            } else if (e.keyCode == 8) { //backspace
                //获取选择文本及光标位置
                rangeData = cursorPosition.get(this);
                if (rangeData.start == rangeData.end) { //此时未选中文本,获取光标位置
                    if (0 == rangeData.end) return; //光标在最开头
                    // 光标前的字符是;
                    if (str.charAt(rangeData.end - 1) == ";") {
                        // 第一个字符是;
                        if (1 == rangeData.end) return;

                        e.preventDefault();
                        // 找到前一个;的位置
                        var start = str.lastIndexOf(";", rangeData.end - 2),
                            end = rangeData.end;

                        setData = {
                            start: start + 1,
                            end: end,
                            startDev: start - rangeData.start + 1,
                            endDev: 0
                        }
                        // 选中该账号
                        cursorPosition.set(this, setData);
                    }
                }
            }
        }
        el.__textareaEvent__ = textareaEvent;
        el.addEventListener('keydown', el.__textareaEvent__);
    },
    unbind(el, binding, vnode) {
    	el.removeEventLister('keydown', el.__textareaEvent__);
        delete el.__textareaEvent__;
    }
}

参考链接:
https://www.cnblogs.com/ranzige/p/4360457.html
http://www.planabc.net/demo/range/textarea-cursor-position.html
https://blog.youkuaiyun.com/lsy649241354/article/details/9081659
https://blog.youkuaiyun.com/skiof007/article/details/6181145?locationNum=5&fps=1

使用python的selenium去模拟人工操作,去对这个https://csc-dm-web-cn-v.huolala.cn/system/dialog-test网站执行文本输入和返回数据的导出操作。 1、在登录需要人工登录,登录页面让我人工去登录以及验证,人工验证完后等待界面进入后,找到title="三轮车-追首培"并点击,然后找到841并点击进入页面,在页面中选择button=系统管理,然后点击ant-menu-item ant-menu-item-only-child进入测试页面,在测试页面中的输入输入信息。 2、我会有一个飞书表格https://huolala.feishu.cn/wiki/N9zFwBPTriCAtakWoDico4udn8b?sheet=8AYeL5&table=tblJrWHuPk159PvI&view=vewsrc24zI,文件里面的字段【对应话术】会存放着我要输入的信息,代码的逻辑是遍历该列的信息去到输入框上输入并点击发送,然后将这个信息发送出去后,找到页面中返回的【intentName】这个字段的数据并下载下来,一直把该列数据的关键词都搜索一遍。并且将放回的数据下载为XLSX文件。下载之后点击清除搜索栏按钮Xpath://*[@id="re-container"]/div[2]/div[1]/div[2]/div/div[2]/form/div/div/div/span/div/div/div,然后继续到飞书表格的对应话术继续执行。 3、在执行的过程中可能会出现一种情况是在点击发送对应话术后,如果出现这个字段【hangUp】为【true】,则需要点击[aria-label="clear"]这个按钮,清楚页面信息,然后重新输入对应话术并发送,然后再继续后面下载的步骤。 5、浏览器的使用为Google 6,需要print程序的过程, 7, 点击为XLSX文件就自动下载以及自动保存了,不需要再设置浏览器下载位置,浏览器的下载不用设置,不会弹窗的 8.点击下载按钮会出现遮挡的情况,要处理这样的情况。 9.代码要简洁点,运行程序间需要高效
最新发布
08-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值