×

Vue设置textarea插入文字光标的位置

2021-07-27 01:49:20 Falcon

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的问题?还是我的代码逻辑问题?

加个 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()
    }
  }
}
本文收录于