允许在 contenteditable 结束时移出跨度

Aar*_*sen 2 html javascript editor contenteditable

我正在尝试使用contenteditable. 在这个 MCVE 中,它只有一个功能,就是给选中的文本一个红色高亮。

我正在使用的代码在这里:

function createSpan() {
    let selection = document.getSelection();
    let range = selection.getRangeAt(0);
    let element = document.createElement("span");
    element.className = "inline-equation";
    range.surroundContents(element);

    let newRange = new Range();
    newRange.selectNodeContents(element);
    selection.removeAllRanges();
    selection.addRange(newRange);
}

$("button").click(createSpan)
Run Code Online (Sandbox Code Playgroud)
.inline-equation {
  background-color: red;
  display: inline-block;
}

#editor {
  width: 100%;
  height: 100%;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>
Create Span
</button>
<div id="editor" contenteditable="true">
This is a contenteditable area.
</div>
Run Code Online (Sandbox Code Playgroud)

我对用户可能会移出突出显示区域并继续输入无格式文本的想法感到困惑。要体验这个问题:

  1. 运行上面的堆栈片段
  2. 从中间的某处选择文本直到最后,然后单击“创建跨度”
  3. 在行尾输入一些新文本

这个新文本也有红色突出显示,即使您试图span通过按右箭头键移出插入的文本。

我仍然希望为用户提供附加格式化的新文本的选项,但同时也允许用户导航出来,span以便他们可以继续输入普通文本。

换句话说,span应该作为一个完全独立的可编辑对象,可以移入或移出。这包括移出span即使在文档末尾的能力,以便用户可以继续输入非格式化文本。

我能给出的最好的例子是 Microsoft Word 的内联方程。请注意,在下面的 GIF 中,方程如何作为一个单独的对象,我可以导航出来,以便我可以在它的右侧键入普通文本。这就是我希望我span的行为方式。

https://i.imgur.com/QEcDhHi.gifv

我试着更换span一个div带有inline-block格式,看看是否能影响的行为,但事实并非如此。我应该如何达到我想要的效果?


在实际用例中,“highlight”实际上表示稍后呈现的 LaTeX 格式的数学。我正在编写本质上是支持内联 LaTeX 的专有标记语言的编辑器。

Tar*_*ani 5

问题是您需要在最后进行一些可编辑的操作才能使其正常工作。有很多相同的现有 SO 线程。你可以在下面看到

为什么我的可编辑光标在 Chrome 中跳到末尾?

contenteditable 将插入符号放在插入的跨度之外

contenteditable 嵌套跨度。谁有重点?

专注于嵌套的 contenteditable 元素

结合上面线程的知识,我能想到的最简单的事情是添加下面的keyup处理程序

$("#editor").on('keyup',(e) => {
  var editor = $("#editor").get(0)
  var cn = editor.childNodes;

  if (cn[cn.length - 1].nodeType !== Node.TEXT_NODE)
  {
     empty = document.createTextNode( '\uFEFF' );
     editor.appendChild(empty);
  }

 if (cn[0].nodeType !== Node.TEXT_NODE)
  {
     empty = document.createTextNode( '\uFEFF' );
     editor.prepend(empty);
  }
})
Run Code Online (Sandbox Code Playgroud)

这确保有一个文本节点可以跳出 div。div如果你愿意,你可以在开始时做同样的事情。下面是相同的 JSFiddle

https://jsfiddle.net/4tcLr0qa/1/

在外面编辑内容