gpt4 book ai didi

javascript - 在 Vue 组件内使用 Rangey 恢复文本范围时出现错误消息 "Marker element has been removed"

转载 作者:行者123 更新时间:2023-11-28 03:36:26 25 4
gpt4 key购买 nike

我有一个相当复杂的 Vue 组件,其中涉及一个 contenteditable div。我想使用 Rangy 突出显示此 div 中的单词并添加其他标记,即使在编辑文本时也保留此标记。

最初,我打算发布一个问题,因为在某些时候处理额外的标记会使 contenteditable div 不可编辑,我只是​​无法删除或添加字符。但是当我尝试设置代码片段时,我收到了另一条错误消息。

编辑 contenteditable div 时,我预计会发生三件事:

  • storeIndexes 方法中,我为 highlights 数组中的每个元素创建并存储范围。该方法称为@beforeinput。此事件并非在所有浏览器中都可用,我使用的是 Chrome。

  • 接下来,我希望更新 contenteditable div 内的文本。

  • 最后,应通过名为 @inputrestoreIndexes 方法恢复范围。

我知道我的代码不应该有任何可见的效果。我的问题是,在尝试编辑文本时出现错误消息: Rangy warning: Module SaveRestore: Marker element has been returned。无法恢复选择。

这里出了什么问题?

new Vue({

el: '#app',

data: {
currentHighlights: [],
highlights: [
{
start: 10,
end: 20
}
],
},

methods: {
// What happens just before an edit is applied
storeIndexes: function(event) {
// Create a new range object
let range = rangy.createRange();

// Get contenteditable element
let container = document.getElementById('text-with-highlights');

// Store all currently highlights and addd DOM markers
this.highlights.forEach(highlight => {
// Move range based on character indexes
range.selectCharacters(container, highlight.start, highlight.end);
// Set DOM markers and store range
this.currentHighlights.push(rangy.saveRange(range))
});
},

// What happens after an edit was made
restoreIndexes: function(event) {
// Create a new range object
let range = rangy.createRange();

// Get range based on character indexes
let container = document.getElementById('text-with-highlights');


this.currentHighlights.forEach(highlight => {
range.selectCharacters(container, highlight.start, highlight.end);
rangy.restoreRange(range);
});


this.currentHighlights = [];
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/rangy/1.3.0/rangy-core.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/rangy/1.3.0/rangy-selectionsaverestore.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/rangy/1.3.0/rangy-textrange.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id='app'>
<div @beforeinput='storeIndexes' @input='restoreIndexes' contenteditable id='text-with-highlights'>
Just some text to show the problem.
</div>
</div>

最佳答案

事实证明,这不是 Vue 问题,而是异步运行的代码之一:当 restoreIndexes 尝试恢复范围时,storeIndexes 尚未完成。

setTimeout 成功了。我不确定是否有比按随机间隔延迟该方法更好的方法,

// What happens after an edit was made
restoreIndexes: function(event) {
setTimeout(() => {
// Create a new range object
let range = rangy.createRange();

// Get range based on character indexes
let container = document.getElementById('text-with-highlights');


this.currentHighlights.forEach(highlight => {
range.selectCharacters(container, highlight.start, highlight.end);
rangy.restoreRange(range);
});
}, 10);

// Restore highlights
this.currentHighlights = [];
},

但是,我可以使用 v-runtime-template 完全摆脱我的 storeIndexes 方法。图书馆。这是 v-html 的替代方案,但也适用于以编程方式插入的元素,例如我的问题中的突出显示。

现在,我的突出显示仅对 $data 中的索引变化使用react,并且在更新 contenteditable div 时我不需要手动移动它们。

关于javascript - 在 Vue 组件内使用 Rangey 恢复文本范围时出现错误消息 "Marker element has been removed",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57695397/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com