关于设置textarea光标位置?

1.需求如下

有一个textarea标签。需要获得光标的位置,并且根据光标的位置插入指定的内容。

通过v-model双向绑定textarea的value值,textarea绑定input事件,当在textarea输入时,能触发input事件,但是通过代码代表value值,无法触发input事件,所以我将value值加入watch里面监听,这样只要value值改变,就能触发watch里面的方法。

2.问题

如上图,光标位置处在最后面,并没有改变光标位置

代码如下:

watch:{
    value:function(val, oldval){
        this.$refs.input.focus();
        this.html = Marked(this.value);
        console.log(this.$refs.input.selectionStart);  // 第一次console
        this.$refs.input.focus();
        // this.start是记录的贯标的位置,同理this.end
        this.$refs.input.selectionStart = this.start + 2;        
        this.$refs.input.selectionEnd = this.end + 2;
        console.log(this.$refs.input.selectionStart); // 比第一次console 多 2
    }
},

实际是改变了this.$refs.input.selectionStart的值得,但是光标位置视觉上是没有改变的,这是为什么?
另外,在纯html文件中试验了一下设置光标位置,是为问题的,是Vue的问题?还是我的代码逻辑问题?

阅读 13.8k
4 个回答

加个 setTimeout 可以,但是有个问题,光标会先在最后一闪,然后马上返回你设置的位置。
可以先blur,然后获取位置,然后focus。
参考

tabDelete (e) { // 自定义默认 tab 事件
  const TABKEY = 9;
  if (e.keyCode === TABKEY) {
    let pos = this.$refs['mTextarea'].selectionStart
    if (pos >= 0) {
      this.input = this.input.splice(pos, '    ')
      this.$refs['mTextarea'].blur()
      setTimeout(() => {
        this.$refs['mTextarea'].selectionStart = pos + 4
        this.$refs['mTextarea'].selectionEnd = pos + 4
        this.$refs['mTextarea'].focus()
      })
    }
    if(e.preventDefault) {
      e.preventDefault()
    }
  }
}
新手上路,请多包涵

你可以试试把设置光标的函数放到 this.$nextTick() 中执行,或者设置一个 settimeout

新手上路,请多包涵

我也遇到这样的问题,设置了,console出来位置也对,但是显示的光标一直在最后面,不知道你是怎样解决的

在使用React时的解决方案

    onKeyDown = (e) => {
        const { text } = this.state;
        console.log(e.key);
        if (e.key === 'Tab') {
            const start = e.target.selectionStart;
            const _text = text.slice(0, start) + '    ' + text.slice(start);
            e.preventDefault();
            e.target.blur();
            this.setState({
                text: _text
            });
            const target = e.target;
            setTimeout(function () {
                target.focus();
                target.selectionStart = start + 4;
                target.selectionEnd = start + 4;
            })
        }
    }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏