Получение позиции текстового узла DOM

Можно ли получить геометрическую позицию (т. Е. Смещения сверху / слева от родительского элемента, страницы и т. Д.) Текстового узла?

5 ответов

Решение

Не напрямую. TextNode не имеет изначально-IE смещения * (и аналогичных) расширений для измерения позиционирования в области просмотра.

Только в IE вы можете создать объект TextRange, кропотливо пытаться выровнять его по границам TextNode, затем измерить boundingLeft/boundingTop для TextRange и добавить его в положение родительского элемента (полученного обычными средствами), Однако это куча работы для потенциально нестабильного решения с одним браузером.

Другим подходом, с которым вам, возможно, удастся обойтись, будет завершение текста в элементе span (либо в документе, либо динамически и / или временно по сценарию), и использование span для измерения позиционирования, при условии, что он не собирает никаких дополнительных стили, которые могут повлиять на позицию. Тем не менее, обратите внимание, что перенесенный интервал может не дать ожидаемых правых / нижних значений; в зависимости от того, что вы хотите с ним сделать, вы можете в конечном итоге обернуть первый и последний символ или что-то другое.

Резюмируя: ничего хорошего.

Сегодня вы можете через Range.getBoundingClientRect(), IE9+

// Get your text node
const el = document.querySelector('strong')
const textNode = el.firstChild;

// Get coordinates via Range
const range = document.createRange();
range.selectNode(textNode);
const coordinates = range.getBoundingClientRect()

console.log(coordinates);
/* Demo CSS, ignore, highlights box coordinates */ body{max-width:300px}strong{position:relative}strong,strong:before{border:solid 1px red}strong:before{content:'';position:absolute;right:100%;bottom:100%;width:100vw;height:100vh;pointer-events:none}
The red lines will show you the coordinates bounding box of the <strong>selected textnode</strong>.

Текстовый узел относительно области просмотра

function getBoundingClientRectText(textNode) {
  const range = document.createRange()
  range.selectNode(textNode)
  return range.getBoundingClientRect()
}

Текстовый узел относительно элемента

function getTextOffsetRelativeToElement(element, textNode) {
  const elementRect = element.getBoundingClientRect()
  const range = document.createRange()
  range.selectNode(textNode)
  const textRect = range.getBoundingClientRect()
  return {
    top: textRect.top - elementRect.top,
    left: textRect.left - elementRect.left
  }
}

Смещение символа относительно родительского элемента текстового узла

function getCharOffset(textNode, offset) {
  const parentRect = textNode.parentElement.getBoundingClientRect()
  const range = document.createRange()
  range.setStart(textNode, offset)
  range.setEnd(textNode, offset + 1)
  const charRect = range.getBoundingClientRect()
  return {
    top: charRect.top - parentRect.top,
    left: charRect.left - parentRect.left
  }
}

Нет встроенного кросс-браузерного способа сделать это. Я бы использовал jQuery с плагином Dimensions: http://brandonaaron.net/docs/dimensions/

Это кросс-браузер и даст вам смещения высоты, ширины и x & y, среди других.

Взгляните на эту статью - она ​​использует свойство offsetParent для рекурсивного вычисления смещения.

Я всегда рекомендовал бы jquery вместо того, чтобы сворачивать ваши собственные методы для разных браузерных вещей, подобных этой. Кажется, что у CSS-функций jquery есть нужные методы!

В эти дни есть способы. Один из способов: getBoundingRectangle: https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect

Другие вопросы по тегам