Obtener la posición de una etiqueta div / span

103

¿Alguien puede mostrarme cómo obtener la posición top& leftde un elemento divo spancuando uno no está especificado?

es decir:

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

En lo anterior, si lo hago:

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

Se 55pxdevuelve el valor de . Sin embargo, si intento eso para span'12a', no se devuelve nada.

Tengo un montón de div/ spans en una página para las que no puedo especificar top/ leftproperties, pero necesito mostrar un divdirectamente debajo de ese elemento.

schmoopy
fuente

Respuestas:

100

Esta función le dirá la posición x, y del elemento en relación con la página. Básicamente, debe recorrer todos los padres del elemento y sumar sus compensaciones.

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

Sin embargo, si solo desea la posición x, y del elemento en relación con su contenedor, entonces todo lo que necesita es:

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

Para colocar un elemento directamente debajo de éste, también necesitará conocer su altura. Esto se almacena en la propiedad offsetHeight / offsetWidth.

var yPositionOfNewElement = el.offsetTop + el.offsetHeight + someMargin;
nickf
fuente
5
Desafortunadamente, este método falla en Chrome cuando el elemento está dentro de una tabla con borde. También fallará en el modo estándar IE6 debido a los márgenes BODY.
GetFree
1
Solo una advertencia para los usuarios de este código. Esto es relativo a la página y no a la ventana. Devuelve el mismo valor si el usuario se desplaza usando las barras de desplazamiento. Ten cuidado.
Isaac Bolinger
gracias @IsaacBolinger lo acabo de notar. ¿Alguien puede decirme cómo puedo cambiar los valores cuando se cambia el tamaño de la ventana o el usuario se desplaza?
David Fariña
@ DavidFariña Usé el módulo de geometría "dom-geometry" de dojo para eso. No sé cómo hacerlo de forma nativa.
Isaac Bolinger
Downvoted: puede resultar obvio para los usuarios más experimentados, pero no ha especificado qué se debe pasar exactamente para el (es decir, proporcione un uso de muestra).
Matt
183

Puede llamar al método getBoundingClientRect()en una referencia al elemento. A continuación, puede examinar las top, left, righty / o bottompropiedades ...

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

Si usa jQuery, puede usar el código más sucinto ...

var offsets = $('#11a').offset();
var top = offsets.top;
var left = offsets.left;
alex
fuente
11
+1 para esta respuesta, getBoundingClientRect()debe usarse, ¡y esta debe ser la respuesta aceptada! Pero no necesita un "navegador moderno" para que esto funcione, consulte la lista de compatibilidad que mostré aquí: stackoverflow.com/questions/1480133/… . Funciona bien en IE 4.0+ (!), Chrome 1.0+, FF 3.0+, Safari 4.0+ y Opera.
Sk8erPeter
25
Tenga en cuenta que getBoundingClientRect()devuelve valores relativos a la ventana gráfica, no al documento. Para eso, querrás algo como top = el.getBoundingClientRect().top + window.pageYOffset - el.ownerDocument.documentElement.clientTop.
Zack Bloom
1
También tenga en cuenta que getBoundingClientRecttiene transformen cuenta.
ExpExc
Esto no es exacto si el primer niño que no está absolutamente posicionado tiene margen superior o margen izquierdo. Actualmente no existe una solución precisa en esta página, por lo que si alguien lo sabe, publique una respuesta.
Curtis
16

Mientras que la respuesta de @ nickf funciona. Si no le interesan los navegadores más antiguos, puede utilizar esta versión pura de Javascript. Funciona en IE9 + y otros

var rect = el.getBoundingClientRect();

var position = {
  top: rect.top + window.pageYOffset,
  left: rect.left + window.pageXOffset
};
Benjamín Intal
fuente
12

Como señaló Alex, puede usar jQuery offset () para obtener la posición relativa al flujo del documento. Utilice position () para sus coordenadas x, y relativas al padre.

EDITAR: Cambiado document.readypor window.loadporque loadespera todos los elementos para que obtenga su tamaño en lugar de simplemente preparar el DOM. En mi experiencia, loadresulta en menos elementos posicionados incorrectamente en Javascript.

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

Para cualquiera que necesite solo la posición superior o izquierda, ligeras modificaciones en el código legible de @ Nickf es suficiente.

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

y

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