分类
Javascript

处理富文本回车换行

上一篇文章,我们通过一个富文本组件并为其自定义了v-module,使其像表单元素一样支持双向数据绑定。但还有不小问题。比如输入回车换行,会在文本上包裹html标签。Chrome中是div,IE中是p,Firefox中是br。当然这些附加的标签在浏览器中显示是Ok的,但有的终端是不支持html标签的,因此得转换它们。

最先想到的是用正则表达式来替换,但不太好匹配,写起来很复杂,改了几版还是有问题。后来换了个思路终于搞定。

insertReturn (el) {
  const range = document.createRange()
  //返回用户当前的选区
  const sel = document.getSelection()
  //获取当前光标位置
  const offset = sel.focusOffset
  //div当前内容
  const content = el.innerHTML
  //添加换行符
  let separator = '\n'
  // 光标在文本最后
  if (offset === content.length) {
    separator = '\n\r'
  }
  el.innerHTML = content.slice(0, offset) + separator + content.slice(offset)
  //设置光标为当前位置
  range.setStart(el.childNodes[0], offset + 1)
  //使得选区(光标)开始与结束位置重叠
  range.collapse(true)
  //移除现有其他的选区
  sel.removeAllRanges()
  //加入光标的选区
  sel.addRange(range)
},
handleKeyDown(event) {
  event.preventDefault()
  this.insertReturn(event.target)
}

这里我们为可编辑div新增了handleKeyDown处理函数,使用event.preventDefault()取消了浏览器在文本回车换行的默认行为。用insertReturn方法来统一处理:使用回车换行来分割字符串,如果是在文本中间用\r\n,文本开头用\n就可以了。代码都有注释,就不细讲了。完整代码参考这里。关于range可以参考我之前写的开发在线文本编辑器

Happy code!