专业编程基础技术教程

网站首页 > 基础教程 正文

vue封装编辑器div设置contenteditable回车光标在开头

ccvgpt 2024-08-02 11:53:58 基础教程 13 ℃

最近封装了一个vue编辑器组件,发现按回车键,换行后,光标定位在开头,而不是回车的地方。

为什么要封装编辑器?

因为我要模拟word的输入,并且需要标记出来输入区域。如下图:

vue封装编辑器div设置contenteditable回车光标在开头

如果使用输入框,则中括号[]标记不会随着文字走,比如内容换行的效果

换行的时候,标记是跟着内容的。


解决方案

使用Selction和Range对象来解决。

通过Selection对象获取光标所在对象,然后通过Range对象获取光标的位置,记录回车时光标的位置,等刷新后再把光标设置回去。

关键代码如下:

      <span
        ref="elInput"
        class="word-text"
        :placeholder="props.placeholder"
        :class="[props.inputClass, { disable: props.disable }]"
        :contenteditable="!props.disable"
        @input="onInputValue"
        @keypress.enter="onKeyPress"
        @keyup.enter="onKeyup"
      >
        {{ props.value || "" }}
      </span>

当按下回车键的时候记录光标位置,回车键结束时重新设置光标位置。

const onKeyPress = (e) => {
  const el = e.target;
  const val = e.target.innerText;
  var selection = window.getSelection();
  var range = selection!.getRangeAt(0);
  // 回车键,记录光标位置
  cursorIndex.value = range.startOffset;
};

const onKeyup = (e) => {
  // 只有光标被标记了,才进行处理
  if (cursorIndex.value <= 0) {
    return;
  }
  const el = e.target;
  const val = e.target.innerText;
  var selection = window.getSelection();
  var range = selection!.getRangeAt(0);
  selection.removeAllRanges();
  // 在光标移动结束后重新设置
  setTimeout(() => {
    // 设置光标开始位置
    range.setStart(el.firstChild, Math.min(cursorIndex.value + 1, val.length));
    // 添加选区
    selection.addRange(range);
    // 清除光标标记
    cursorIndex.value = 0;
  }, 0);
};

上面就是解决方案,有的人我看直接在一个keyup事件中就解决了,我试了在keyup中处理不管用。

Tags:

最近发表
标签列表