最近做项目遇到这样一个需求,可以往输入框指定光标出插入内容,并且当删除插入的内容时会先将插入的内容进行光标选中给用户进行提示,当再次删除时才删除内容。而这个需求的核心就在 setSelectionRange(设置光标位置) 这个dom api上,找到他就都简单了。
一、实现光标插入
实现光标插入首先需要我们在输入框失去焦点时记录下光标的位置,然后就很简单了,做一个字符串的分割和拼接就搞定。
<div>
<span>模板变量:</span>
<ul class="vira">
<li v-for="(item, ind) in labelSuffix.propList" :key="item.valuie"
@click="insertVal(item.code)">
{{ item.code }}
</li>
</ul>
</div>
<el-input @blur="campaignNameBlur" type="textarea" maxlength="400" show-word-limit
@keydown.delete.native="del" :autosize="{ minRows: 4, maxRows: 10 }"
v-model="template.content">
</el-input>
<script>
data(){
retrun{
template:{
content:""//输入框内容
},
labelSuffix:{
propList: [
{valuie: "{GoodsLink}", code: "#商品详情#"},
{valuie: "{OrderLink}", code: "#订单详情#"}
],
},
cursorPosition:""//保存光标位置
}
}
methods:{
// 失去焦点时保存光标位置
campaignNameBlur(e) {
this.cursorPosition = e.srcElement.selectionStart
},
// 插入内容
insertVal(val) {
let num = this.cursorPosition
let type = typeof num
let cont = this.template.content
if (type == "number") {//插入到指定光标处
let right = cont.slice(0, num)
let left = cont.slice(num)
this.template.content = right + val + left
} else {//没有指定插入直接添加到最后
this.template.content += val;
}
},
}
<script/>
二、设置光标位置,提示用户删除操作
del(e) {
let content = this.template.content
if(!content)return//没有内容就不用进行后面操作
let start = e.target.selectionStart//光标起始位置
let end = e.target.selectionEnd//光标结束位置
if(start == end){//删除操作判断,
let left = content.slice(end-6,end)
let right = content.slice(end-1,end+5)//因为我们的变量长度都为6,所以截取左右长
度为6的字符串
let arr = this.labelSuffix.propList.map(item=>item.code)
if(arr.includes(left)){//判断变量中是否存在,存在则设置光标位置,不存在则不用管
e.target.setSelectionRange(end-6,end)//设置光标位置
e.preventDefault()//阻止浏览器的默认行为,防止删除
}else if(arr.includes(right)){
e.target.setSelectionRange(end-1,end+5)
e.preventDefault()
}
}
},
最后就此完成,如下为附上效果视频