uniapp中input、textarea获取光标和光标聚焦

3,653 阅读2分钟

最近公司做web即时聊天项目,uniapp在输入框内容这一块算是有个小坑

场景

项目有发表情的功能,发表情的功能需要通过鼠标点击表情。重点就是鼠标点击表情后,输入框就会失焦,光标也会消失,这样自然表情就输入不进去。

只能通过自己拼接内容了🤨,而拼接内容就涉及到获取光标和设置光标了。

一般获取光标位置和设置光标位置都是通过js操作DOM完成,可是uniapp里面只能获取DOM,不能操作DOM。于是我去uniapp官方文档看一看相关的api,很遗憾只找到了获取光标位置的api,并没有设置光标的api。

想了想,并不一定非要设置光标,我的目标只是拼接内容,这样来说有替代方案,只要在点击表情输入框失焦后根据获取的光标位置拼接完内容再重新聚焦就好了。

解决

1、获取光标位置api:

image.png

uni.getSelectedTextRange官方文档

举个例子:

uni.getSelectedTextRange({
    //有三个回调:success、fail、complete
    success: (res) => {
        //res有两个属性
        console.log(`光标起始位置:${res.start},光标结束位置:${end}`)
    },
});

在回调里面把光标位置保存起来

2、设置input或textarea的focus属性

image.png

focus属性要为true

3、手动聚焦

因为我是点击了表情才失焦,那么手动聚焦和拼接内容的代码就放在表情的点击事件里。

使用第一步获取的光标位置先把光标前和光标后的内容存起来再和新内容拼接:

//inputContentIndex:光标位置
let strBefore = this.inputContent.substr(0,this.inputContentIndex)
let strAfter = this.inputContent.substr(this.inputContentIndex, this.inputContent.length-1)
this.inputContent = strBefore + m + strAfter
this.inputContentIndex +=m.length

在聚焦之前需要先给input或者textarea加上ref
再使用_focus方法:

this.$refs.inputContentEl._focus()

当然也可以查找到input或者textarea的元素使用focus方法:

this.$refs.inputContentEl.$el.children[0].children[1].focus()

两个方法效果一样。

注意: 多行的内容最好使用textarea,input虽然也会跟着输入的内容向后移动,它聚焦后光标的位置也在最后一位,但视图的可是区域不会显示在最后。