Получить позицию тега div / span


103

Может ли кто-нибудь показать мне, как получить top& leftпозицию элемента divили, spanесли он не указан?

то есть:

<span id='11a' style='top:55px;' onmouseover="GetPos(this);">stuff</span>
<span id='12a' onmouseover="GetPos(this);">stuff</span>

В приведенном выше случае, если я это сделаю:

document.getElementById('11a').style.top

Значение 55pxвозвращается. Однако, если я попробую это для span«12а», то ничего не вернется.

У меня есть куча div/ spans на странице, для которой я не могу указать свойства top/ left, но мне нужно отображать divпрямо под этим элементом.

Ответы:


100

Эта функция сообщит вам позицию x, y элемента относительно страницы. По сути, вам нужно перебрать все родительские элементы и сложить их смещения.

function getPos(el) {
    // yay readability
    for (var lx=0, ly=0;
         el != null;
         lx += el.offsetLeft, ly += el.offsetTop, el = el.offsetParent);
    return {x: lx,y: ly};
}

Однако, если вам просто нужна позиция x, y элемента относительно его контейнера, то все, что вам нужно, это:

var x = el.offsetLeft, y = el.offsetTop;

Чтобы разместить элемент прямо под этим, вам также необходимо знать его высоту. Это сохраняется в свойстве offsetHeight / offsetWidth.

var yPositionOfNewElement = el.offsetTop + el.offsetHeight + someMargin;

5
К сожалению, этот метод не работает в Chrome, когда элемент находится внутри таблицы с рамкой. Он также не будет работать в стандартном режиме IE6 из-за полей BODY.
— GetFree

1
Просто предупреждение для пользователей этого кода. Это относится к странице, а не к окну. Он возвращает то же значение, если пользователь выполняет прокрутку с помощью полос прокрутки. Быть осторожен.
— Исаак Болинджер

спасибо @IsaacBolinger только что заметил это. Может ли кто-нибудь сказать мне, как мне заставить его изменять значения при изменении размера окна или при прокрутке пользователем?
— Дэвид Фаринья

@ DavidFariña Для этого я использовал геометрический модуль "dom-geometry" додзё. Я не знаю, как это сделать изначально.
— Исаак Болинджер

Проголосовано против - это может быть очевидно для более опытных пользователей, но вы не указали, что именно нужно передать для el (например, предоставьте пример использования).
— Мэтт

184

Вы можете вызвать метод getBoundingClientRect()по ссылке на элемент. Затем вы можете проверить top, left, rightи / или bottomсвойства ...

var offsets = document.getElementById('11a').getBoundingClientRect();
var top = offsets.top;
var left = offsets.left;

Если вы используете jQuery, вы можете использовать более сжатый код ...

var offsets = $('#11a').offset();
var top = offsets.top;
var left = offsets.left;

11
getBoundingClientRect()Следует использовать +1 для этого ответа - и это должен быть принятый ответ! Но вам не нужен «современный браузер», чтобы это работало, см. Список совместимости, который я показал здесь: stackoverflow.com/questions/1480133/… . Он отлично работает в IE 4.0+ (!), Chrome 1.0+, FF 3.0+, Safari 4.0+ и Opera.
— Sk8erPeter

25
Обратите внимание, что getBoundingClientRect()возвращает значения относительно области просмотра, а не документа. Для этого вам понадобится что-то вроде top = el.getBoundingClientRect().top + window.pageYOffset - el.ownerDocument.documentElement.clientTop.
— Zack Bloom

1
Также обратите внимание , что getBoundingClientRectпринимает transformво внимание.
— ExpExc

Это неверно, если у первого дочернего элемента с неабсолютным позиционированием есть margin-top или margin-left. В настоящее время на этой странице нет точного решения, поэтому, если кто-нибудь знает, отправьте ответ.
— Curtis

16

Хотя ответ @ nickf работает. Если вам не нравятся старые браузеры, вы можете использовать эту чистую версию Javascript. Работает в IE9 + и др.

var rect = el.getBoundingClientRect();

var position = {
  top: rect.top + window.pageYOffset,
  left: rect.left + window.pageXOffset
};

12

Как заметил Алекс, вы можете использовать jQuery offset () для получения позиции относительно потока документов. Используйте position () для его координат x, y относительно родителя.

РЕДАКТИРОВАТЬ: переключено document.readyна, window.loadпотому что loadожидает всех элементов, поэтому вы получаете их размер, а не просто готовите DOM. По моему опыту, это loadприводит к меньшему количеству неправильно позиционированных элементов Javascript.

$(window).load(function(){ 
  // Log the position with jQuery
  var position = $('#myDivInQuestion').position();
  console.log('X: ' + position.left + ", Y: " + position.top );
});

9

Для тех, кому нужно только верхнее или левое положение, небольшие изменения в читаемом коде @ Nickf помогут.

function getTopPos(el) {
    for (var topPos = 0;
        el != null;
        topPos += el.offsetTop, el = el.offsetParent);
    return topPos;
}

и

function getLeftPos(el) {
    for (var leftPos = 0;
        el != null;
        leftPos += el.offsetLeft, el = el.offsetParent);
    return leftPos;
}

2

Я понимаю, что это старая ветка, но ответ @alex необходимо пометить как правильный.

element.getBoundingClientRect() точно соответствует jQuery $(element).offset()

И он совместим с IE4 + ... https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect


Вам нужно будет указать смещение прокрутки страницы
— Бенджамин Интал,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.