javascript - 允许在 contenteditable 的末尾移出 span

标签 javascript html 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)
.inline-equation {
  background-color: red;
  display: inline-block;
}

#editor {
  width: 100%;
  height: 100%;
}
<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>

我对用户可能移出高亮区域并继续输入无格式文本的想法感到困惑。要遇到此问题:

  1. 运行上面的堆栈代码段
  2. 从中间的某个位置选择文本直到最后,然后单击Create Span
  3. 在行尾键入一些新文本

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

我仍然想让用户选择附加格式化的新文本,但也允许用户导航到 span 之外,以便他们可以继续键入普通文本.

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

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

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

我已经尝试用 inline-block 格式将 span 替换为 div 以查看是否影响了行为,但它没有't。我应该如何实现我正在寻找的效果?


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

最佳答案

问题是您需要在末尾添加一些可编辑的内容才能使其正常工作。有很多相同的现有 SO 线程。你可以在下面看到

Why Is My Contenteditable Cursor Jumping to the End in Chrome?

contenteditable put caret outside inserted span

contenteditable with nested span. Who has the focus?

Focusing on nested contenteditable element

结合上面线程的知识,我能想到的最简单的事情是在 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);
  }
})

这确保有一个文本节点可以跳出 div。如果需要,您可以对起始 div 做同样的事情。下面是相同的 JSFiddle

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

Edit content outside

关于javascript - 允许在 contenteditable 的末尾移出 span,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50556307/

相关文章:

javascript - 获取裁剪后的 DIV 的全高

javascript - 无法正确使用 Jquery.load() 功能

html - Adobe Edge Code 和 Brackets 有什么区别?

javascript - Material Design lite 对话框在 Safari 桌面和手机中呈现

javascript - 如何在超链接 DataGridView 中放置确认

javascript - html 表单 - 无需 php 将文件上传到存储

unix - 你妈妈从未告诉过你的 Vim 的阴暗角落是什么?

javascript - 使用 enzyme 测试 React Native FlatList

javascript - Next.js 页面过渡

德尔福编辑器。光标样式