Безопасное разделение содержимого div на дочерний элемент или строку в javascript - PullRequest
0 голосов
/ 10 июля 2020

Привет, я пытаюсь безопасно разделить контент на 2 div, откуда находится курсор, и вызовет функцию split Html при нажатии клавиши Enter

Пример contenteditable

сценарий 1

 <span id="editor" contenteditable>
     Welcome something
     <div>sample content <i>here 1</i></div>
     <div>Sample  <b><i><u>content|*here is my cursor*</u></i></b> here 2</div>
     <div>Sample content <b>here 3</b></div>
     <div>Sample content here 4</div>
    </span>

сценарий 2

<span id="editor" contenteditable>
 Welcome something|*here is my cursor*
 <div>sample content <i>here 1</i></div>
 <div>Sample  <b><i><u>content</u></i> here 2</div>
 <div>Sample content <b>here 3</b></div>
 <div>Sample content here 4</div>
</span>

если я запустил код

function splitHtml(el){
   //code
   console.log(splitedResult)
}

Ожидаемый сценарий splitedResult для 1

[
 '<span contenteditable>Welcome something<div>sample content <i>here 1</i></div></span>',
 '<span contenteditable><div>Sample content <b>here 3</b></div><div>Sample content here 4</div></span>'
]

Ожидаемый splitedResult в сценарии 2

[
 '<span contenteditable><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>'
]

Спасибо за то, что любой может мне помочь

Ответы [ 2 ]

1 голос
/ 13 июля 2020

Я не уверен, что это именно то, что вам нужно, но вы можете использовать что-то вроде этого:

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) создаст глубокий клон (клонирует узел и дочерние узлы).

0 голосов
/ 10 июля 2020

let x;
let y;


function handleKeydown(e) {
  if (e.keyCode === 13) {
    e.preventDefault();
    let target = window.getSelection().anchorNode.parentElement;
    if (["I", "B"].some(tag => tag === target.tagName)) target = target.parentElement;
    splitHtml(target);
  }

}


function splitHtml(target) {
  const editable = document.getElementById("editor");
  const innerHTML = editable.innerHTML;
  const split = innerHTML.split(target.outerHTML);
  const output = split.map(ele => "<span contenteditable>" + ele + "</span>");
  //console.log(output)
  document.getElementById("container").innerHTML = output.reduce((t, c) => t + c);
}
<div>Input: </div>
<br/>

<span id="editor" contenteditable onkeydown="handleKeydown(event)">
             <span>Welcome</span>
             <div>sample content <i>here 1</i></div>
             <div>Sample content|*here is my cursor* here 2</div>
             <div>Sample content <b>here 3</b></div>
             <div>Sample content here 4</div>
        </span>

   
<br/>
<div>Output:</div>
<br/>

<div id="container">


</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...