Как посчитать длину текста от корневого div до focusNode?

#javascript #html

#javascript #HTML

Вопрос:

Представьте, что у меня есть дерево узлов (верхнего уровня root ) с кучей подузлов, например:

 <div id="root" contenteditable="true" >
  Inside div <span>Inside span </span><a>Inside link </a><span>Inside span </span>Inside div again
</div>
 

Когда я нажимаю в любом месте внутри этого div , я получаю focusNode значение, основанное на моем щелчке (простой щелчок, а не щелчок и удержание, чтобы сделать выбор).

 const selection = window.getSelection();
const focusNode = selection.focusNode; // This is the node where the caret is
 

ВОПРОС

Как я могу посчитать текст от root , пока не найду focusNode ? Обход всех возможных дочерних элементов и добавление каждой длины текста по пути. Когда focusNode найдено, верните общее значение.

Примечание: я не использую jQuery.

 function handleClick() {
  const root = document.getElementById('root');
  const selection = window.getSelection();
  const focusNode = selection.focusNode;
  
  countTextFromRootToFocus(root,focusNode);
}


function countTextFromRootToFocus(root,focusNode) {

  console.log('Text length from root to focus is: XXX');
} 
 #root {
  border: 1px dotted blue;
} 
 <p>Click anywhere inside the div</p>
<div id="root" contenteditable="true" onclick="handleClick()">
  Inside div <span>Inside span </span><a>Inside link </a><span>Inside span </span>Inside div again
</div> 

Комментарии:

1. какой вариант использования это будет иметь? (что вы планируете делать дальше с этой длиной / индексом) — может помочь в создании решений 🙂

2. Я создаю поле упоминания, похожее на поле «новый твит» в Твиттере. Где вы можете ввести «@», и он автоматически заполнится списком пользователей. Если вы проверите Twitter, вы увидите, что каждая строка внутри поля твита — это a <div> , но когда вы упоминаете кого-то, это упоминание становится a <span> внутри <div> . Я использую React, и я установлю innerHTML div для их создания, <span> а также удалю их. Но innerHTML сбрасывает курсор в начало строки. Итак, мне нужно посчитать, где это было, чтобы я мог поместить его обратно после изменения html.

3. jsfiddle.net/abhas9/61n4adrk

4. jsfiddle.net/nrx9yvw9/5 не отправляю, потому что это не мой код

5. @AbhasTandon еще раз спасибо! Это действительно хороший фрагмент кода!