Пошук позиції елемента щодо документа


113

Який найпростіший спосіб визначити положення елементів відносно документа / тіла / вікна браузера?

Зараз я використовую .offsetLeft/offsetTop, але цей метод дає вам лише положення відносно батьківського елемента, тому вам потрібно визначити, скільки батьків до елемента тіла, щоб знати положення відносного до положення тіла / вікна браузера / документа.

Цей спосіб теж громіздкий.

Відповіді:


58

Ви можете пройти offsetParentдо верхнього рівня DOM.

function getOffsetLeft( elem )
{
    var offsetLeft = 0;
    do {
      if ( !isNaN( elem.offsetLeft ) )
      {
          offsetLeft += elem.offsetLeft;
      }
    } while( elem = elem.offsetParent );
    return offsetLeft;
}

28
Ні, це не так, коли будь-який з батьків (особливо html-елемент !!!) має поля, прокладки або межі.
Спалах Грім

що стосується матеріалів поля ... це може допомогти встановити розміри поля для межі поля ... або щось уздовж цих ліній ... нічого, що неможливо виправити ...

По-перше, вам потрібно вирішити, чи враховувати межу та маржу відповідно до розміру поля. По-друге, слід враховувати згорнуту маржу. І останнє, в майбутньому буде складніша ситуація, яка б погіршила цю відповідь.
xianshenglu

6
Чому це прийнята відповідь? Це застаріло і погано працює. Зробіть собі послугу і використовуйте getBoundingClientRect (), як пропонується в інших відповідях.
Fabian von Ellerts

177

Ви можете дістатись зверху та зліва, не переходячи DOM так:

function getCoords(elem) { // crossbrowser version
    var box = elem.getBoundingClientRect();

    var body = document.body;
    var docEl = document.documentElement;

    var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
    var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;

    var clientTop = docEl.clientTop || body.clientTop || 0;
    var clientLeft = docEl.clientLeft || body.clientLeft || 0;

    var top  = box.top +  scrollTop - clientTop;
    var left = box.left + scrollLeft - clientLeft;

    return { top: Math.round(top), left: Math.round(left) };
}

6
Ця відповідь не враховує компенсації батьків. Це лише щодо огляду
Nickey

3
@ Nickey, що не відповідає дійсності - положення вікна перегляду, а також перевірки зміщення прокрутки, дають координати відносно всього документа.
natchiketa

1
Може бути помилка на мобільних пристроях stackoverflow.com/a/32623832/962634 Потрібні дослідження
базилік

1
Чому ви віднімаєте clientTop / clientLeft?
Темох

1
@Teemoh clientTop / clientLeft відповідає значенням межі <html>елемента.
Рафаель Рафатпанах

98

Ви можете використовувати element.getBoundingClientRect()позицію елемента відносно вікна перегляду.

Потім використовуйте document.documentElement.scrollTopдля обчислення зміщення вікна перегляду.

Сума двох дасть положення елемента щодо документа:

element.getBoundingClientRect().top + document.documentElement.scrollTop

10
Відносно вікна перегляду не те саме, що відносно документа. Якщо сторінка прокручується трохи вниз, то верхнє відносно вікна перегляду буде меншим числом, ніж верхнє відносно документа.
MrVimes

14
він починається відносно вікна перегляду та додає прокруткуY, щоб отримати його відносно документа.
Хоакін Куєнка Абела

2
document.documentElement.scrollTopне працює в Safari, використовуйте window.scrollYзамість цього
Fabian von Ellerts

7

Я пропоную використовувати

element.getBoundingClientRect()

як запропоновано тут замість ручного розрахунку зміщення через offsetLeft , offsetTop та offsetParent . як запропоновано тут. За певних обставин * ручний обхід дає недійсні результати. Дивіться цей Plunker: http://plnkr.co/pC8Kgj

* Коли елемент знаходиться всередині батьків, який прокручується, зі статичним (= за замовчуванням) позиціонуванням.


Ви можете зробити розрахунок зміщення також, включивши в нього scrollLeft та scrollTop.
Ben J

Але я знайшов offsetLeftі offsetTopне беру до уваги перетворення CSS3, що getBoundingClientRect()і є. Тож це випадок, якщо результати можуть бути недійсними. Якщо вам це потрібно, ви можете отримати зміщення елемента щодо батьківського (наприклад offsetLeft), використовуючи (element.getBoundingClientRect().left - parent.getBoundingClientRect().left).
Бен Дж

слід дефіксувати вище; ці значення набагато корисніші, і все також за один дзвінок!
mix3d

7

document-offset( Сторонній сценарій ) цікавий, і, здається, використовуються підходи з інших відповідей тут.

Приклад:

var offset = require('document-offset')
var target = document.getElementById('target')
console.log(offset(target))
// => {top: 69, left: 108} 

5

Наступний метод виявився найнадійнішим у вирішенні крайових випадків, які вимикають офсетTop / offsetLeft.

function getPosition(element) {
    var clientRect = element.getBoundingClientRect();
    return {left: clientRect.left + document.body.scrollLeft,
            top: clientRect.top + document.body.scrollTop};
}

4

Для тих, хто хоче отримати координати x і y різних положень елемента відносно документа.

const getCoords = (element, position) => {
  const { top, left, width, height } = element.getBoundingClientRect();
  let point;
  switch (position) {
    case "top left":
      point = {
        x: left + window.pageXOffset,
        y: top + window.pageYOffset
      };
      break;
    case "top center":
      point = {
        x: left + width / 2 + window.pageXOffset,
        y: top + window.pageYOffset
      };
      break;
    case "top right":
      point = {
        x: left + width + window.pageXOffset,
        y: top + window.pageYOffset
      };
      break;
    case "center left":
      point = {
        x: left + window.pageXOffset,
        y: top + height / 2 + window.pageYOffset
      };
      break;
    case "center":
      point = {
        x: left + width / 2 + window.pageXOffset,
        y: top + height / 2 + window.pageYOffset
      };
      break;
    case "center right":
      point = {
        x: left + width + window.pageXOffset,
        y: top + height / 2 + window.pageYOffset
      };
      break;
    case "bottom left":
      point = {
        x: left + window.pageXOffset,
        y: top + height + window.pageYOffset
      };
      break;
    case "bottom center":
      point = {
        x: left + width / 2 + window.pageXOffset,
        y: top + height + window.pageYOffset
      };
      break;
    case "bottom right":
      point = {
        x: left + width + window.pageXOffset,
        y: top + height + window.pageYOffset
      };
      break;
  }
  return point;
};

Використання

  • getCoords(document.querySelector('selector'), 'center')

  • getCoords(document.querySelector('selector'), 'bottom right')

  • getCoords(document.querySelector('selector'), 'top center')


2

Якщо ви не проти використовувати jQuery, то ви можете використовувати offset()функцію. Щоб отримати докладнішу інформацію про цю функцію, зверніться до документації .


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.