В моем приложении мне нужно вычислить offsetLeft элемента с абсолютным позиционированием, но проблема в том, что он глубоко вложен, поэтому при выполнении element.current.offsetLeft я получаю offsetLeft относительно ...

1
سعيد 19 Мар 2021 в 19:16

2 ответа

Лучший ответ

Функция getOffsetLeft не обязательно должна быть асинхронной, поскольку ни один из атрибутов, к которым осуществляется доступ для получения прямоугольника смещения для элемента, не должен быть асинхронным.

Вы, наверное, ищете что-то вроде

function getCumulativeOffsetLeft(element) {
  let offsetLeft = 0;
  while (element && element.tagName !== "BODY") {
    offsetLeft += element.offsetLeft;
    element = element.parentElement;
  }
  return offsetLeft;
}

Который выполняет внутреннюю "рекурсию" (обход дерева вверх).

2
AKX 19 Мар 2021 в 16:20

Вы можете использовать для этого рекурсию, но не обязательно, чтобы она была асинхронной -

const recursiveOffsetLeft = elem =>
  elem?.tagName == "BODY"
    ? 0
    : elem?.offsetLeft + recursiveOffsetLeft(elem.parentElement)

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

Одно улучшение, которое я вижу здесь, позволяет вызывающему абоненту указывать точку остановки -

const recursiveOffsetLeft = (elem, rel = document.body) =>
  elem === rel
    ? 0
    : elem?.offsetLeft + recursiveOffsetLeft(elem.parentElement, rel)

Это позволяет вызывающему повторно использовать эту функцию для вычисления смещений различной глубины -

recursiveOffsetLeft(someElem) // defaults to document.body
recursiveOffsetLeft(someElem, someParent) // <-
0
Thank you 19 Мар 2021 в 16:51