javascript - 当 HTML 在内容可编辑 DIV 中更新时,Vanilla JavaScript 可保存和恢复插入符号位置
问题描述
我知道在StackOverflow和Google上有很多类似的问题的答案,我尝试了很多,但没有一个有效。所以我将在下面发布我自己的代码,希望有人可以提供帮助。提前致谢。
注意:当我手动输入此问题时,以下代码中可能存在拼写错误。如果他们让您感到困惑,我已经检查并为任何不便表示歉意。
我试图在该
contenteditable
DIV 中实现的逻辑:
- DIV 中的用户类型
- 同时,事件侦听器正在检查用户输入的文本并使用预定义的关键字数组进行过滤,例如
['apple', 'banana']
. 过滤后的文本将包装在 HTML 中并写回 DIV。 - 在实现上述目的的同时,用户不会丢失鼠标插入符号,这意味着此扫描和替换过程应该在后台不断发生,并且不会影响用户的编辑。
编码:
HTML(处理前)
<div id="editor">
Mr Jenkins has an apple and a banana.
</div>
HTML(处理后)
<div id="editor">
Mr Jenkins has an <u>apple</u> and a <u>banana</u>.
</div>
JavaScript(它在vue
所以我在这里跳过了其他部分并在vanilla
这里显示)
计划 A使用预定义的选择变量
这会引发错误“DOMException:
Failed to execute 'collapse' on 'Selection': There is no child at offset 7"
// Global variable to store the offset value when DOM content loaded
// The input event of the #editor element is listened but skipped here
var caretPosition,
selection = window.getSelection();
function scanText() {
let editor = document.getElementById('editor');
// Save the position
caretPosition = selection.focusOffset;
// Scan and replace text
editor.innerHTML = filterText(); // Function filterText will return HTML as in above example
// Restore the position
selection.collapse(editor, caretPosition);
}
计划 B在旅途中使用获取选择
这不会引发任何错误,但插入符号位置很奇怪该focusOffset
值远小于实际focusOffset
值。例如,如果focusOffset
在Plan A is 中100
,它9
在Plan B中。所以它总是在错误的位置恢复
function scanText() {
let editor = document.getElementById('editor');
// Save the position
caretPosition = window.getSelection().focusOffset;
// Scan and replace text
editor.innerHTML = filterText(); // Function filterText will return HTML as in above example
// Restore the position
window.getSelection().collapse(editor, caretPosition);
}
计划 C使用范围
“IndexSizeError:无法在 'Range' 上执行 'setStart':偏移 5 处没有子级。”
function scanText() {
let editor = document.getElementById('editor'),
offsets, range = new Range();
// Save the range
// It starts at 5 and ends at 101 though I only placed cursor at the end of the text
if (window.getSelection().rangeCount) {
offsets = [
window.getSelection().getRangeAt(0).startOffset, // 5
window.getSelection().getRangeAt(0).endOffset // 101
];
}
// Scan and replace text
editor.innerHTML = filterText(); // Function filterText will return HTML as in above example
// Restore the range
range.setStart(editor, offsets[0]); // Set start container to editor and start offset as 5
range.setEnd(editor, offsets[1]); // Set end container to editor and end offset as 101
}
解决方案
推荐阅读
- c# - 如何判断 C# 项目是否正在使用 SSD 构建?
- r - 如何为 r 文本分析创建定制的贸易/法律词典
- css - CSS 关键帧动画在 Chrome 和 Firefox 中停止工作
- excel - *EXCEL* 如果一系列单元格包含 *STRING*,则从正单元格中提取十进制数的总和
- php - 如何从 HTML/PHP 页面打印 png/jpg 文件?
- c# - 通过 csproj 文件中的 PackageReference 更新 nuget 包
- r - 忽略 x-label 对齐与拼凑而成的多个图:这可能吗?
- node.js - 在node.js中的回调中带有等待的递归函数
- android-studio - 在颤动中将文件添加到git忽略
- python - 排除给定值之前的所有 Null 值(熊猫)