2009-08-29 17 views
80

Quiero obtener la posición de un elemento relativo a la ventana del navegador (la ventana en la que se muestra la página, no toda la página). ¿Cómo se puede hacer esto en JavaScript?¿Cómo obtener la posición superior de un elemento con respecto a la ventana del navegador?

Muchas gracias

+2

Creo que esta pregunta es similar a http://stackoverflow.com/questions/211703/is-it- possible-to-get-the-position-of-div-within-the-browser-viewport-not-withi, que tiene una solución realmente agradable. –

+0

@JakobRunge, ¿eso fue "bueno" en 2013? –

+1

Considera aceptar una solución. –

Respuesta

11

Editar: añadir algo de código para dar cuenta de la página de desplazamiento.

function findPos(id) { 
    var node = document.getElementById(id);  
    var curtop = 0; 
    var curtopscroll = 0; 
    if (node.offsetParent) { 
     do { 
      curtop += node.offsetTop; 
      curtopscroll += node.offsetParent ? node.offsetParent.scrollTop : 0; 
     } while (node = node.offsetParent); 

     alert(curtop - curtopscroll); 
    } 
} 

El argumento id es la identificación del elemento cuyo desplazamiento que desee. Adaptado de quirksmode post.

+0

Gracias por su respuesta, pero creo que no entendió mi pregunta, sé cómo obtener la parte superior de un elemento relativo a la página, lo que estoy tratando de hacer es obtener la posición relativa a la 'ventana gráfica' (es decir, el navegador ventana, no el documento) –

+0

Lo siento, su uso de 'viewport' me tiró. Entonces, ¿estás diciendo que quieres contabilizar el navegador Chrome, es decir, la barra de herramientas de marcadores, la barra de direcciones, etc.? –

+0

No, solo la ventana a través de la cual ves la página. Si la página se desplaza, será diferente de la parte superior del documento, de lo contrario, son iguales. –

1

La función en la página this devolverá un rectángulo con las coordenadas superior, izquierda, altura y ancho de un elemento pasado en relación con el puerto de vista del navegador.

localToGlobal: function(_el) { 
     var target = _el, 
     target_width = target.offsetWidth, 
     target_height = target.offsetHeight, 
     target_left = target.offsetLeft, 
     target_top = target.offsetTop, 
     gleft = 0, 
     gtop = 0, 
     rect = {}; 

     var moonwalk = function(_parent) { 
     if (!!_parent) { 
      gleft += _parent.offsetLeft; 
      gtop += _parent.offsetTop; 
      moonwalk(_parent.offsetParent); 
     } else { 
      return rect = { 
      top: target.offsetTop + gtop, 
      left: target.offsetLeft + gleft, 
      bottom: (target.offsetTop + gtop) + target_height, 
      right: (target.offsetLeft + gleft) + target_width 
      }; 
     } 
    }; 
     moonwalk(target.offsetParent); 
     return rect; 
} 
4

Usted puede tratar de:

node.offsetTop - window.scrollY

Funciona en Opera con visor etiqueta meta definida.

+2

Si entiendo [la documentación] (https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop) correctamente, 'offsetTop' es relativo al elemento posicionado más cercano. Que, dependiendo de la estructura de la página, puede ser o no un elemento raíz. –

0

Gracias por todas las respuestas. Parece que Prototype ya tiene una función que hace esto (la función de página()). Al ver el código fuente de la función, descubrí que primero calcula la posición del desplazamiento del elemento en relación con la página (es decir, la parte superior del documento), y luego resta el scrollTop de eso. Vea el código fuente del prototipo para más detalles.

+0

Buena decisión. Probablemente sea mejor ir con una de las principales bibliotecas, ya que es más probable que den el mismo resultado en todos los navegadores. Si tienes curiosidad, verifica mi respuesta. El código allí lo hará, pero no tengo idea de cómo se mantendrá en todos los navegadores. –

173

Las respuestas existentes ahora están desactualizadas. El método nativo getBoundingClientRect() ha existido desde hace bastante tiempo y hace exactamente lo que la pregunta requiere. Además de que es compatible con todos los navegadores (como Internet Explorer 5, que parece!)

De MDN page:

El valor devuelto es un objeto TextRectangle, que contiene sólo lectura a la izquierda, arriba, derecha y propiedades inferiores describiendo el cuadro de borde, en píxeles, con la esquina superior izquierda relativa a la esquina superior izquierda de la ventana gráfica.

que lo utilice de esta manera:

var viewportOffset = el.getBoundingClientRect(); 
// these are relative to the viewport, i.e. the window 
var top = viewportOffset.top; 
var left = viewportOffset.left; 
+2

Es posible que esto no funcione correctamente cuando utilice el zoom del navegador (Android Chrome). La solución de @rism ([ver a continuación] (http://stackoverflow.com/a/1350681/2757230) funciona en este caso – Dmitry

+2

Bueno para la mayoría de los casos, pero se supone que el elemento no está dentro de un iframe incrustado, ¿verdad? La pregunta es sobre la relativa ventana del navegador. El.getBoundingClientRect() devolverá relativa la ventana del iframe, no la ventana del navegador. – cakidnyc

+1

La pregunta es acerca de la relativa ventana del navegador. –

1

estoy asumiendo un elemento que tiene un id de btn1 existe en la página web, y también que se incluye jQuery. Esto ha funcionado en todos los navegadores modernos de Chrome, FireFox, IE> = 9 y Edge. jQuery solo se usa para determinar la posición relativa al documento.

var screenRelativeTop = $("#btn1").offset().top - (window.scrollY || 
              window.pageYOffset || document.body.scrollTop); 

var screenRelativeLeft = $("#btn1").offset().left - (window.scrollX || 
              window.pageXOffset || document.body.scrollLeft); 
+0

jQuery es JavaScript. Creo que quisiste decir _ "no es 100% vanilla/pure JS". _ – hungerstar

+0

Sí, eso es lo que quise decir. – Sunil

+0

jquery is terrible – Tobiq

14

En mi caso, sólo para estar seguro en cuanto a desplazamiento, que añade el window.scroll a la ecuación:

var element = document.getElementById('myElement'); 
var topPos = element.getBoundingClientRect().top + window.scrollY; 
var leftPos = element.getBoundingClientRect().left + window.scrollX; 

que me permite obtener la posición relativa real del elemento en el documento, incluso si ha sido desplazado.

+2

¿No se supone que debes agregar la posición de desplazamiento en lugar de restarla? –

+0

Volví a subir la respuesta, pero aún así, @lulian Onofrei tiene razón. Por favor edita. – pmrotule

+0

@Fabio 'getBoundingClientRect(). Top' no está en mi IE11 devuelve 0. ¿Tiene alguna solución? – Arif

0

A veces getBoundingClientRect() el valor de la propiedad del objeto muestra 0 para IE. En ese caso, debe establecer display = 'block' para el elemento. Puede usar el código a continuación para que todos los navegadores obtengan compensación.

funcionalidad Extender jQuery:

(function($) { 
    jQuery.fn.weOffset = function() { 
     var de = document.documentElement; 
     $(this).css("display", "block"); 
     var box = $(this).get(0).getBoundingClientRect(); 
     var top = box.top + window.pageYOffset - de.clientTop; 
     var left = box.left + window.pageXOffset - de.clientLeft; 
     return { top: top, left: left }; 
    }; 
}(jQuery)); 

Uso:

var elementOffset = $("#" + elementId).weOffset(); 
0

creo que jQuery se llevan a la práctica de una manera muy elegante. Si nos fijamos en la fuente para offset, encontrará que esto es básicamente la forma en que lo implementan:

var rect = elem.getBoundingClientRect(); 
var win = elem.ownerDocument.defaultView; 

return { 
    top: rect.top + win.pageYOffset, 
    left: rect.left + win.pageXOffset 
}; 
Cuestiones relacionadas