Obtenha a posição de uma tag div / span


103

Alguém pode me mostrar como obter a top& leftposição de um elemento divou spanquando um não está especificado?

ie:

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

Acima, se eu fizer:

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

O valor de 55pxé retornado. No entanto, se eu tentar fazer isso para span'12a', nada será retornado.

Eu tenho um monte de div/ spans em uma página para a qual não posso especificar as propriedades top/ left, mas preciso exibir um divdiretamente sob esse elemento.

Respostas:


100

Esta função informará a posição x, y do elemento em relação à página. Basicamente, você deve percorrer todos os pais do elemento e adicionar seus deslocamentos.

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};
}

No entanto, se você quiser apenas a posição x, y do elemento em relação ao seu contêiner, tudo o que você precisa é:

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

Para colocar um elemento diretamente abaixo deste, você também precisará saber sua altura. Isso é armazenado na propriedade offsetHeight / offsetWidth.

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

5
Infelizmente, esse método falha no Chrome quando o elemento está dentro de uma tabela com borda. Ele também falhará no modo padrão do IE6 devido às margens do BODY.
— GetFree

1
Apenas um aviso para os usuários deste código. Isso é relativo à página e não à janela. Ele retorna o mesmo valor se o usuário rolar usando as barras de rolagem. Seja cuidadoso.
— Isaac Bolinger

obrigado @IsaacBolinger acabei de notar. Alguém pode me dizer como faço para alterar os valores quando a janela é redimensionada ou o usuário rola?
— David Fariña

@DavidFariña, usei o módulo de geometria "dom-geometry" do dojo para isso. Não sei como fazer nativamente.
— Isaac Bolinger

Downvoted - Pode ser óbvio para usuários mais experientes, mas você não especificou o que exatamente precisa ser passado para el (ou seja, forneça um exemplo de uso).
— Matt

184

Você pode chamar o método getBoundingClientRect()em uma referência ao elemento. Em seguida, você pode examinar os top, left, righte / ou bottompropriedades ...

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

Se estiver usando jQuery, você pode usar o código mais sucinto ...

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

11
getBoundingClientRect()Deve ser usado +1 para esta resposta - e esta deve ser a resposta aceita! Mas você não precisa de um "navegador moderno" para que isso funcione, veja a lista de compatibilidade que mostrei aqui: stackoverflow.com/questions/1480133/… . Funciona bem no IE 4.0+ (!), Chrome 1.0+, FF 3.0+, Safari 4.0+ e Opera.
— Sk8erPeter

25
Observe que getBoundingClientRect()retorna valores relativos à janela de visualização, não ao documento. Para isso, você quer algo parecido top = el.getBoundingClientRect().top + window.pageYOffset - el.ownerDocument.documentElement.clientTop.
— Zack Bloom

1
Observe também que getBoundingClientRectleva transformem consideração.
— ExpExc

Isso não é preciso se o primeiro filho não posicionado de forma absoluta tiver margem superior ou margem esquerda. No momento, não há uma solução precisa nesta página, então se alguém souber, poste uma resposta.
— Curtis de

16

Enquanto a resposta de @nickf funcionar. Se você não liga para navegadores mais antigos, pode usar esta versão Javascript puro. Funciona no IE9 + e outros

var rect = el.getBoundingClientRect();

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

12

Como Alex observou, você pode usar jQuery offset () para obter a posição relativa ao fluxo do documento. Use position () para suas coordenadas x, y relativas ao pai.

EDIT: Alternado document.readypara window.loadporque loadespera por todos os elementos para que você obtenha seus tamanhos em vez de simplesmente preparar o DOM. Na minha experiência, loadresulta em menos elementos posicionados em Javascript incorretamente.

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

9

Para qualquer um que precise apenas da posição superior ou esquerda, pequenas modificações no código legível de @Nickf resolvem o problema.

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

e

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.