Я не уверен, что это именно то, что вам нужно, но вы можете использовать что-то вроде этого:
function nodePath(baseNode, targetNode, currentPath = []) {
if (baseNode == targetNode) return currentPath;
currentPath.unshift(targetNode);
return nodePath(baseNode, targetNode.parentNode, currentPath);
}
document.getElementById("editor").addEventListener("keydown", event => {
const {currentTarget: editor, code} = event;
if (code != "Enter") return;
event.preventDefault();
const cursorNode = window.getSelection().anchorNode;
const [child] = nodePath(editor, cursorNode);
const wrappers = Array.from({length: 2}, () => editor.cloneNode(false));
wrappers.forEach(wrapper => wrapper.removeAttribute("id"));
let seenChild = false;
for (const node of editor.childNodes) {
if (!seenChild && node == child) {
seenChild = true;
} else if (!seenChild) {
wrappers[0].append(node.cloneNode(true));
} else {
wrappers[1].append(node.cloneNode(true));
}
}
console.log("output:");
wrappers.forEach(wrapper => console.log(wrapper.outerHTML));
});
<span id="editor" contenteditable>
Welcome something
<div>sample content <i>here 1</i></div>
<div>Sample <b><i><u>content</u></i></b> here 2</div>
<div>Sample content <b>here 3</b></div>
<div>Sample content here 4</div>
</span>
Обратите внимание, что в настоящее время я делаю копию вашего текущего элемента #editor
для создания оболочки, но вы можете довольно легко создать новый узел с нуля.
Функция nodePath
прослеживает targetNode
обратно до baseNode
. Например, <a><b><c></c></b></a>
. Если <a>
- это baseNode
, а <c>
- это targetNode
. Тогда nodePath
вернет массив [<b>, <c>]
.
cloneNode(false)
создаст неглубокий клон (клонирует узел без дочерних узлов). cloneNode(true)
создаст глубокий клон (клонирует узел и дочерние узлы).