【问题标题】:Caret position in editable div after prop change using Vue.js使用 Vue.js 更改道具后可编辑 div 中的插入符号位置
【发布时间】:2019-11-29 16:12:58
【问题描述】:

我正在使用 Vue.js 并有以下代码。 当我输入 div 并更新 this.content 时,插入符号总是重置到开头。

<template>
<div> 
  <div contenteditable="true"
    v-html="content"
    @input="onContentChange($event)">
  </div>
</div>
</template>
<script>
export default {
  props: ['content'],
  methods: {
    onContentChange: function(e) {
      this.content = e.target.innerHTML;
    },
  }, 
}
</script>
<style>
</style>

如何保留插入符号的位置并更新内容?

我看过其他一些类似的帖子,但那里的解决方案要么不适用于 Vue.js,要么不适用于我的情况,或者我可能无法正确应用它们。

【问题讨论】:

  • 你为什么要替换content?它已经包含编辑并且在最后一个位置有插入符号。如果您替换了 innerHTML,它将有效地在您的视图中构建新元素,并且很明显,它会丢失插入符号的位置。你基本上有两种情况,你需要区分它们:当编辑来自用户时(在这种情况下你不想替换content)和当编辑来自外部源时。如果您希望在第二种情况下保留插入符号,请查看here
  • 1.不,this.content 尚未包含编辑。当我添加 console.log(this.content) 时,它会显示旧文本。注意 v-html 并且它不是输入或文本区域。 2. 那篇文章是关于获得职位的,但我有问题而不是设置职位。
  • 我的意思是您不必将编辑后的值 (e.target.innerHTML) 分配给 content。因此,您有更改 (e.target.innerHTML) 和插入符号的位置。不要指望content 会更新到您的最新编辑(不是v-model,而是v-html)。当content 发生变化时,它只会用最新值content 替换innerHTML。如果您需要v-model 行为,请使用&lt;textarea&gt;v-model。但是,同样,您已经有了编辑和插入符号的位置。你想达到什么目的?
  • 基本上,最后我想将选定的部分文本包装在一些标签中而不会丢失插入符号的位置。但是,如果我更改 this.content 或 innerHTML,插入符号的位置会被重置。所以我需要恢复插入符号的位置。

标签: vue.js vuejs2


【解决方案1】:

首先我们保留当前对 contenteditable 的点击,然后更改 HTML 内容,并设置新的选择。

const range = document.getSelection().getRangeAt(0)
const pos = range.endOffset

this.$el.innerHTML = this.content

const newRange = document.createRange()
const selection = window.getSelection()
const node = this.$el.childNodes[0]
newRange.setStart(node, node && pos > node.length ? 0 : pos)
newRange.collapse(true)
selection.removeAllRanges()
selection.addRange(newRange)

【讨论】:

    【解决方案2】:

    我已经测试了几个场景,我认为您真正需要的显然是this post 中的创建可重复使用的可编辑组件

    但是,如果您想在一个组件中包含所有内容,则在 chrome 中可以使用以下代码:

    <template>
      <div
        ref="editable"
        contenteditable
        @input="onInput"
      >
      </div>
    </template>
    
    <script>
    export default {
      data () {
        return {
          content: 'hello world'
        }
      },
      mounted () {
        this.$refs.editable.innerText = this.content
      },
      methods: {
        onInput (e) {
          this.content = e.target.innerText
        }
      }
    }
    </script>
    

    请注意,在这种情况下,Chrome 中的 Vue 插件似乎无法正确更新 content 的值,因此您必须单击 vue 插件右上角的刷新。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-10
      • 1970-01-01
      • 2017-03-22
      • 1970-01-01
      • 1970-01-01
      • 2020-07-24
      • 2011-10-07
      • 1970-01-01
      相关资源
      最近更新 更多