Получить позицию тега 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.