JavaScript:当用户点击输入并且插入符号在 html 节点内时,如何正确处理 contenteditable 中的内容中断?

问题描述

我正在开发一个简单的块编辑器系统,当用户在块之间点击输入时,我正在努力移动/设置块之间的内容。 假设我有这个可编辑的 div,插入符号显示为“|”下面:

<p contenteditable="true">this is my <strong><em>content |with</em> some styles</strong></p>

如果我按回车键,我想实现这个:

<p contenteditable="true">this is my <strong><em>content </em></strong></p>
<p contenteditable="true"><strong><em>with</em> some styles</strong></p>

更准确地说,我已经在处理节点创建(例如上面的 p 标签在 enter 键上)。

用户点击进入并且光标位于 html 节点内时,我正在努力处理内容本身。此处,插入符号位于 strongem 节点内。我发现很难(1)确定它的确切位置,如果像上面一样涉及多个 HTML 子节点,并且(2)相应地拆分内部内容(“这是我的一些样式的内容”)并重新分配 {{1} } 和 <strong> 标记,它们在逻辑上应该位于两行。

此外,有多个 <em> 元素是有意的,也是当前的约束。

非常感谢在纯 JavaScript 中对此的一些指导。谢谢!

解决方法

如果有人遇到同样的问题,我是这样解决的:

// START: Somewhere in my code
const wrapper = document.querySelector('.wrapper') // Content wrapper
wrapper.addEventListener('keydown',handleKeyDown)

const handleKeyDown = (e) => {
  if (e.keyCode === 13) { // User hits enter
    e.preventDefault() // cancel enter
    // ... other logic
    splitContent(e.target) // call my method to split content if required
  }
}
// END: Somewhere in my code

// the method that solved my issue,using Range and Selection objects
const splitContent = (node) => {
  const range = window.getSelection().getRangeAt(0)
  // Select the end node and its offset from the caret
  range.setStart(range.endContainer,range.endOffset);
  // End the selected range at the end of the node content 
  range.setEnd(node,node.childNodes.length) 
  // Extract content from the defined range (the key is here)
  const content = range.extractContents() 
  // Call another method to use this extracted content with formatting intact
  doWhateverWithTheExtractedContent(content)
}