Получить диапазон начальных и конечных значений смещения, не учитывая его непосредственного родителя - PullRequest
4 голосов
/ 07 июня 2019

У меня есть два span элемента внутри тега p. При выделении некоторого текста в этом p мне нужно получить начальное и конечное смещение выбранного значения, используя window.getSelection().

Я ожидаю, что при выборе второго span текста, подобного 'country', начальное смещение будет 28, а конечное смещение будет 34 без учета его непосредственного родителя. Однако фактическое значение начального смещения составляет 10, а конечное смещение - 16.

Как мне соответствовать ожидаемым значениям?

<p style="margin: 0px;">
  <span>Welcome to India which</span>
  <span>
    <span>was great country for tourist places</span>
  </span>
</p>
private onKeyUp(event: any): void {
  let labelSelection = window.getSelection ? window.getSelection() : document.getSelection();
  let range: any = this.labelSelection.getRangeAt(0);
}

1 Ответ

0 голосов
/ 07 июня 2019

Это довольно сложная проблема, но с ней было приятно поиграть.

Вот один день, чтобы сделать это:

Присоедините прослушиватели событий мыши к содержащему элементу.Используйте event.target, чтобы определить начальный и конечный узлы, которые были выбраны.Используйте эти узлы, чтобы добавить смещения к числам, указанным в необработанном выделении.

Html:

<p id="outer" style="margin: 0px;">
  <span>Welcome to India which</span>
  <span>
    <span>was great country for tourist places</span>
  </span>
</p>

Javascript:

const flattenNodes = node =>
  Array.from(node.children).reduce((acc, curr) => {
    if (curr.childElementCount > 0) {
      acc.push(flattenNodes(curr))
    } else {
      acc.push(curr)
    }
    return acc
  }, [])

const getOffsetForElementAtIndex = nodes => elementIndex =>
  nodes.reduce((sum, node, i) => (i < elementIndex ? sum + node.textContent.length : sum), 0)

const getSelection = ev => {
  const nodes = flattenNodes(ev.currentTarget).flat()
  const startElementIndex = nodes.indexOf(mouseDownElement)
  const endElementIndex = nodes.indexOf(ev.target)
  const { startOffset, endOffset } = document.getSelection().getRangeAt(0)

  const start = startOffset + getOffsetForElementAtIndex(nodes)(startElementIndex)
  const end = endOffset + getOffsetForElementAtIndex(nodes)(endElementIndex)
  console.log(`start: ${start}, end: ${end}`)
}
let mouseDownElement = null

const el = document.getElementById('outer')
el.addEventListener('mousedown', ev => (mouseDownElement = ev.target))
el.addEventListener('mouseup', ev => getSelection(ev))

здесь кодовый код

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