当 HTML 在内容可编辑 DIV

时间:2021-01-20 01:13:45

标签: javascript selection caret

我知道在 StackOverflowGoogle 上有很多类似的问题和答案,我尝试了很多,但没有一个有效。所以我将在下面发布我自己的代码,希望有人可以提供帮助。提前致谢。

注意:当我手动输入此问题时,以下代码中可能存在拼写错误。如果他们让您感到困惑,我已经检查并为给您带来的任何不便表示歉意。

<块引用>

我试图在 contenteditable DIV 中实现的逻辑:

  1. DIV 中的用户类型
  2. 与此同时,事件侦听器正在检查用户输入的文本并使用预定义的关键字数组(例如 ['apple', 'banana'])进行过滤。过滤后的文本将包含在 HTML 中并写回 DIV。
  3. 在实现上述功能的同时,用户不会丢失鼠标插入符,这意味着此扫描和替换过程应在后台不断进行,并且不会影响用户的编辑。
<块引用>

代码:

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 值。 例如,如果 Plan A 中的 focusOffset100,则它是 Plan B 中的 9。 所以总是在错误的位置恢复

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
}

0 个答案:

没有答案