Había estado usando estas 7 líneas de código que funcionan en todos los navegadores con discrepancias en ie5,6,7 (no recordaba tener ningún problema ... puede ser el tipo de documento) ... quirksmode.org/js/findpos. HTML y lo había estado usando mucho durante tantos años. Puede ser sombody puede señalar las fallas si las hay.
Jayapal Chandran
99
@AnthonyWJones, supongo que necesitabas el placer pedante, pero es obvio, como siempre cuando no se especifica, que el OP se refiere al caso más general, o se refiere a las coordenadas de la ventana del navegador.
Motes
77
@Mote, no, no es tan obvio. Deje de lado la inferencia, la subjetividad y los axiomas falsos. Puede ser relativo a la vista o al inicio de la página (también conocido como document.documentElement).
Andre Figueiredo
16
Por defecto, el más general no es inferencia, es la progresión lógica, por lo que sería relativo a la ventana, o "parte superior de la página" podría ser el término tal como lo pones. En Game Theory, se codifica como un concepto llamado punto de Schelling. Asegúrese de especificar cuándo no se refiere al caso más general.
var rect = element.getBoundingClientRect();
console.log(rect.top, rect.right, rect.bottom, rect.left);
Internet Explorer lo ha respaldado desde que es probable que le importe y finalmente se estandarizó en las vistas CSSOM . Todos los demás navegadores lo adoptaron hace mucho tiempo .
Algunos navegadores también devuelven propiedades de alto y ancho, aunque esto no es estándar. Si le preocupa la compatibilidad del navegador anterior, consulte las revisiones de esta respuesta para una implementación degradante optimizada.
Los valores devueltos por element.getBoundingClientRect()son relativos a la ventana gráfica. Si lo necesita en relación con otro elemento, simplemente reste un rectángulo del otro:
var bodyRect = document.body.getBoundingClientRect(),
elemRect = element.getBoundingClientRect(),
offset = elemRect.top - bodyRect.top;
alert('Element is '+ offset +' vertical pixels from <body>');
No funciona ... está a 8 píxeles vertical y horizontalmente, debido al margen de 8 píxeles en el cuerpo. La solución de Meouw funciona perfectamente. Si quieres tengo una pequeña prueba para demostrar el problema.
CpnCrunch 01 de
3
En realidad, creo que depende de lo que realmente quieras obtener. La pregunta es un poco ambigua. Su respuesta es correcta si solo desea las coordenadas relativas a la ventana gráfica o al elemento del cuerpo, pero eso no lo ayuda en el caso en que desea la posición absoluta del elemento (que imagino es lo que la mayoría de la gente quiere) . la respuesta de meouw tampoco te da eso, a menos que elimines los bits '-scrollLeft' y '-scrollTop'.
CpnCrunch
44
@CpnCrunch: veo a qué te refieres ahora; No me di cuenta de que te referías a la última parte de mi respuesta. Cuando el cuerpo tiene un margen, su cuadro delimitador se compensará con ese número de píxeles en cada lado respectivo. En ese caso, también tendría que restar el estilo de margen calculado de las coordenadas del cuerpo. Sin <body>embargo, vale la pena señalar que los reinicios de CSS eliminan el margen .
Andy E
3
element.getBoundingClientRect().topno devuelve el desplazamiento superior correcto en el caso de un position: fixedelemento en iOS (iPhone 8) si contiene un elemento de entrada enfocado y el teclado virtual se ha deslizado hacia arriba. Por ejemplo, si el desplazamiento real desde la parte superior de la ventana es de 200 px, lo informaría como 420 px, donde 220 px es la altura del teclado virtual. Si configura los elementos position: absolutey los coloca en la misma posición que si fueran fijos, obtendrá el 200px correcto. No sé una solución para esto.
Jānis Elmeris
327
Las bibliotecas hacen todo lo posible para obtener compensaciones precisas para un elemento.
Aquí hay una función simple que hace el trabajo en todas las circunstancias que he probado.
function getOffset( el ){var _x =0;var _y =0;while( el &&!isNaN( el.offsetLeft )&&!isNaN( el.offsetTop )){
_x += el.offsetLeft - el.scrollLeft;
_y += el.offsetTop - el.scrollTop;
el = el.offsetParent;}return{ top: _y, left: _x };}var x = getOffset( document.getElementById('yourElId')).left;
cambiar: el = el.parentNode a: el = el.offsetParent; y parece funcionar para iframes anidados ahora ... ¿Creo que eso es lo que pretendías?
Adam el
44
Esta solución está incompleta. Intenta poner un borde grueso en un div y anidéalo varias veces. En cualquier versión de Firefox (2-5) estará desactivado por el ancho de los bordes (incluso en modo de cumplimiento de estándares).
ck_
3
¿No hay una forma más limpia de hacer eso, como una función el.totalOffsetLeft y totalOffsetTop? jQuery ciertamente tiene esta opción, pero es una pena que no haya un método oficial para esto, ¿debemos esperar DOM4? Estoy creando una aplicación de lienzo HTML5, por lo que creo que la mejor solución sería insertar un elemento de lienzo en un iframe para poder obtener coordenadas reales con clientX y clientY cuando hacemos clic en el elemento.
baptx
1
Entonces, @Adam y meouw, ¿estás diciendo que el primer bloque de código está mal? Entonces, ¿por qué no eliminar eso por completo? (Esta pregunta ha visto a muchos espectadores a lo largo de los años; ¿podría ser bueno eliminar las cosas si están equivocadas?)
Arjan
2
@baptx: Sé que esta es una respuesta tardía, pero no vi tu comentario antes. Vea mi respuesta a continuación para obtener una alternativa más compatible con los estándares: realmente ni siquiera necesita el código de respaldo, ya que los navegadores lo han soportado durante mucho tiempo.
Andy E
242
Esto funcionó para mí (modificado de la respuesta más votada):
function getOffset(el){const rect = el.getBoundingClientRect();return{
left: rect.left + window.scrollX,
top: rect.top + window.scrollY
};}
Solo esta solución funciona para mí cuando el elemento se coloca en divcuyo centrado usando CSS top:50%, left:50%; transform:translate(-50%, -50%);... excelente. De acuerdo con la pregunta de @ScottBiggs. Lógico es buscar la simplicidad.
nelek
3
tal vez no sea un ganador porque es lo mismo que la solución de Andy E, pero no funciona en navegadores antiguos <IE9
niltoid
getBoundingClientRect causa un pico de repintado masivo en mis gráficos de rendimiento
frumbert
1
Debe definir rectel uso de var, leto const. De lo contrario, se define como window.rect.
hev1
2
left: rect.left + window.scrollX + (rect.width / 2), top: rect.top + window.scrollY + (rect.height / 2)devolverá la posición media de un elemento
abhishake
97
Si desea que se haga solo en javascript , aquí hay algunos liners que usangetBoundingClientRect()
window.scrollY + document.querySelector('#elementId').getBoundingClientRect().top // Y
window.scrollX + document.querySelector('#elementId').getBoundingClientRect().left // X
La primera línea devolverá offsetTopdecir Y en relación con el documento. La segunda línea devolverá offsetLeftdecir X en relación con el documento.
getBoundingClientRect() es una función de JavaScript que devuelve la posición del elemento en relación con la ventana gráfica de la ventana.
Esta debería ser la solución. No hay un código bs largo aquí, ¡es comprensible y muy preciso!
E Alexis MT
2
¿Qué pasa si el elemento está dentro de un elemento desplazable? La única forma de hacerlo es sumar la compensación de la parte superior de todos los elementos principales, como sugieren otras respuestas
Dmitri Pisarev
Como dice Dmitri, esto es incorrecto y muy defectuoso. No debería tener tantos votos como lo hace. SIEMPRE también estará en un elemento desplazable porque el documento en sí puede desplazarse. En otras palabras, a menos que todo el documento se ajuste a la ventana gráfica, siempre será incorrecto si el usuario ha desplazado la ventana principal.
Lev
46
Los elementos HTML en la mayoría de los navegadores tendrán: -
offsetLeft
offsetTop
Estos especifican la posición del elemento en relación con su padre más cercano que tiene diseño. A menudo se puede acceder a este padre mediante la propiedad offsetParent.
IE y FF3 tienen
clientLeft
clientTop
Estas propiedades son menos comunes, especifican una posición de los elementos con el área del cliente principal (el área acolchada es parte del área del cliente pero el borde y el margen no lo son).
Si la página incluye, al menos, cualquier "DIV", la función dada por meouw arroja el valor "Y" más allá de los límites actuales de la página. Para encontrar la posición exacta, debe manejar tanto offsetParent's como parentNode's.
Pruebe el código que figura a continuación (se verifica para FF2):
Al igual que con las otras soluciones, incluso con FF 24.4, el código anterior no funciona cuando existen anchos de borde como parte del diseño de posicionamiento.
robar
Eres un salvavidas. Estoy trabajando a través de algunos errores de GWT bastante profundos en este momento y lanzar esto en un método JSNI resuelve todos mis problemas.
Will Byrne
35
Puede agregar dos propiedades para Element.prototypeobtener la parte superior / izquierda de cualquier elemento.
la modificación Element.prototypegeneralmente se considera una mala idea . Conduce a un código realmente difícil de mantener. Además, este código no tiene en cuenta el desplazamiento.
Jared Forsyth
23
Para recuperar la posición relativa a la página de manera eficiente y sin usar una función recursiva: (también incluye IE)
var element = document.getElementById('elementId');//replace elementId with your element's Id.var rect = element.getBoundingClientRect();var elementLeft,elementTop;//x and yvar scrollTop = document.documentElement.scrollTop?
document.documentElement.scrollTop:document.body.scrollTop;var scrollLeft = document.documentElement.scrollLeft?
document.documentElement.scrollLeft:document.body.scrollLeft;
elementTop = rect.top+scrollTop;
elementLeft = rect.left+scrollLeft;
Incluyendo el importante scrollTop / scrollLeft hace que esta respuesta sea un poco más correcta.
scunliffe
19
¿Qué tal algo como esto? Al pasar la ID del elemento y devolverá la izquierda o la parte superior, también podemos combinarlos:
1) encontrar a la izquierda
function findLeft(element){var rec = document.getElementById(element).getBoundingClientRect();return rec.left + window.scrollX;}//call it like findLeft('#header');
2) encontrar la parte superior
function findTop(element){var rec = document.getElementById(element).getBoundingClientRect();return rec.top + window.scrollY;}//call it like findTop('#header');
o 3) encontrar izquierda y arriba juntos
function findTopLeft(element){var rec = document.getElementById(element).getBoundingClientRect();return{top: rec.top + window.scrollY, left: rec.left + window.scrollX};}//call it like findTopLeft('#header');
Es posible que le sirva mejor utilizando un marco de JavaScript, que tiene funciones para devolver dicha información (¡y mucho más!) De forma independiente del navegador. Aquí hay algunos:
@Costa Todos usan ese tipo de funciones, aunque este es un campo en evolución, ya que los diferentes navegadores se ajustan de manera diferente a la especificación. Gran parte del código trata de "arreglar" las cosas que salen mal. Realmente deberías mirar el código fuente.
Shalom Craimer
18
@scraimer: ¡jQuery y YUI NO son marcos ! Estas son bibliotecas ! No es lo mismo. Citando jquery.com : "jQuery es una biblioteca de JavaScript rápida, pequeña y rica en funciones ". Citando yuilibrary.com (también se puede ver la palabra "mágica" en la URL ...): "YUI es una biblioteca gratuita de código abierto de JavaScript y CSS para crear aplicaciones web ricamente interactivas".
Sk8erPeter
29
Entonces, ¿debería usar bibliotecas enormes solo para esta tarea simple? No es necesario. Odio que cada vez que quiero hacer algo con js, obtengo estas soluciones jQuery. jQuery no es JS!
Opptatt Jobber
1
@OpptattJobber Estoy de acuerdo ... JQuery no es javascript. Se basa en Javascript pero es un lenguaje de programación completamente diferente.
Nick Manning
55
@NickManning No es un lenguaje nuevo, es una capa de abstracción para el DOM que elimina la necesidad de escribir soluciones de compatibilidad y rendimiento directamente en su código. Si no usa jQuery, debería estar usando algún tipo de capa de abstracción de todos modos.
ginman
15
jQuery .offset () obtendrá las coordenadas actuales del primer elemento, o establecerá las coordenadas de cada elemento, en el conjunto de elementos coincidentes, en relación con el documento.
Por alguna razón, no está dando los mismos resultados en IE en comparación con otros navegadores. Creo que en IE está dando una posición relativa a la ventana, por lo que si se desplaza, obtendrá diferentes resultados en IE en comparación con otros
Abdul Rahim Haddad
1
offset () se confunde con el zoom, al menos en Android Chrome, por lo que es inútil. stackoverflow.com/a/11396681/1691517 muestra una forma tolerante al zoom.
Timo Kähkönen
10
Tomé la respuesta de @ meouw, agregué el clientLeft que permite el borde y luego creé tres versiones:
getAbsoluteOffsetFromBody - similar a @ meouw's, esto obtiene la posición absoluta en relación con el cuerpo o el elemento html del documento (dependiendo del modo peculiaridades)
getAbsoluteOffsetFromGivenElement: devuelve la posición absoluta en relación con el elemento dado (relativeEl). Tenga en cuenta que el elemento dado debe contener el elemento el, o esto se comportará igual que getAbsoluteOffsetFromBody. Esto es útil si tiene dos elementos contenidos dentro de otro elemento (conocido) (opcionalmente, varios nodos en el árbol de nodos) y desea colocarlos en la misma posición.
getAbsoluteOffsetFromRelative: devuelve la posición absoluta relativa al primer elemento padre con position: relative. Esto es similar a getAbsoluteOffsetFromGivenElement, por la misma razón, pero solo irá hasta el primer elemento coincidente.
getAbsoluteOffsetFromBody =function( el ){// finds the offset of el from the body or html elementvar _x =0;var _y =0;while( el &&!isNaN( el.offsetLeft )&&!isNaN( el.offsetTop )){
_x += el.offsetLeft - el.scrollLeft + el.clientLeft;
_y += el.offsetTop - el.scrollTop + el.clientTop;
el = el.offsetParent;}return{ top: _y, left: _x };}
getAbsoluteOffsetFromGivenElement =function( el, relativeEl ){// finds the offset of el from relativeElvar _x =0;var _y =0;while( el && el != relativeEl &&!isNaN( el.offsetLeft )&&!isNaN( el.offsetTop )){
_x += el.offsetLeft - el.scrollLeft + el.clientLeft;
_y += el.offsetTop - el.scrollTop + el.clientTop;
el = el.offsetParent;}return{ top: _y, left: _x };}
getAbsoluteOffsetFromRelative =function( el ){// finds the offset of el from the first parent with position: relativevar _x =0;var _y =0;while( el &&!isNaN( el.offsetLeft )&&!isNaN( el.offsetTop )){
_x += el.offsetLeft - el.scrollLeft + el.clientLeft;
_y += el.offsetTop - el.scrollTop + el.clientTop;
el = el.offsetParent;if(el !=null){if(getComputedStyle !=='undefined')
valString = getComputedStyle(el,null).getPropertyValue('position');else
valString = el.currentStyle['position'];if(valString ==="relative")
el =null;}}return{ top: _y, left: _x };}
Si todavía tiene problemas, particularmente en relación con el desplazamiento, puede intentar mirar http://www.greywyvern.com/?post=331 . Noté al menos una pieza de código cuestionable en getStyle que debería estar bien asumiendo que los navegadores se comporten bien , pero no he probado el resto en absoluto.
Interesante ... pero en Edge getAbsoluteOffsetFromBody (element) .top devuelve un valor diferente a medida que me desplazo, en Chrome se mantiene constante a medida que me desplazo. Parece que Edge se está ajustando con la posición de desplazamiento. Cuando el elemento se desplaza fuera de la vista, obtengo un valor negativo.
Norman
getAbsoluteOffsetFromRelative hizo mi día, tuve que reproducir la información sobre herramientas de bootstrap sin Javascript de bootstrap, me ayudó mucho.
Nolyurn
En caso de que Meouw cambie su nombre de usuario, enlace para responder: stackoverflow.com/a/442474/3654837 . (No quiero subir esto hilo de edad así que sí, puesto en comentario)
Mukyuu
8
si usa jQuery, el complemento de dimensiones es excelente y le permite especificar exactamente lo que desea.
p.ej
Posición relativa, posición absoluta, posición absoluta sin relleno, con relleno ...
Continúa, digamos que hay mucho que puedes hacer con él.
Además, la ventaja de usar jQuery es su tamaño de archivo ligero y fácil de usar, no volverá a JavaScript sin él después.
Este es el mejor código que he logrado crear (también funciona en iframes, a diferencia del desplazamiento de jQuery ()). Parece que webkit tiene un comportamiento un poco diferente.
Basado en el comentario de meouw:
function getOffset( el ){var _x =0;var _y =0;while( el &&!isNaN( el.offsetLeft )&&!isNaN( el.offsetTop )){
_x += el.offsetLeft - el.scrollLeft;
_y += el.offsetTop - el.scrollTop;// chrome/safariif($.browser.webkit){
el = el.parentNode;}else{// firefox/IE
el = el.offsetParent;}}return{ top: _y, left: _x };}
function getPosition( el ){var x =0;var y =0;while( el &&!isNaN( el.offsetLeft )&&!isNaN( el.offsetTop )){
x += el.offsetLeft - el.scrollLeft;
y += el.offsetTop - el.scrollTop;
el = el.offsetParent;}return{ top: y, left: x };}
Desafortunadamente, esto no funciona para todos los elementos que uno puede encontrar dentro de un documento HTML moderno. Embedded <svg>elementos, por ejemplo, no tienen offsetLeft, offsetTopy offsetParentpropiedades.
Jonathan Eunice
Es justo DIVo IMGno SVG. Ver "Buscar un ejemplo de coordenadas"? puede encontrar el objeto svg es llamar a la posición getOffsetRect , intente y dependa del trabajo del objeto.
KingRider
7
El enfoque más limpio que he encontrado es una versión simplificada de la técnica utilizada por jQuery offset. Similar a algunas de las otras respuestas con las que comienza getBoundingClientRect; luego usa el windowy el documentElementpara ajustar la posición de desplazamiento, así como elementos como el margen en body(a menudo el predeterminado).
Si bien es muy probable que esto se pierda al final de tantas respuestas, las mejores soluciones aquí no me funcionaron.
Por lo que pude ver, ninguna de las otras respuestas habría ayudado.
Situación :
en una página HTML5 tenía un menú que era un elemento de navegación dentro de un encabezado (no EL encabezado sino un encabezado en otro elemento).
Quería que la navegación se mantuviera en la parte superior una vez que un usuario se desplazara hacia ella, pero antes de esto, el encabezado estaba en una posición absoluta (para que pudiera superponer algo más).
Las soluciones anteriores nunca activaron un cambio porque .offsetTop no iba a cambiar ya que este era un elemento de posición absoluta. Además, la propiedad .scrollTop era simplemente la parte superior del elemento más superior ... es decir 0 y siempre sería 0.
Cualquier prueba que realicé utilizando estos dos (y lo mismo con los resultados de getBoundingClientRect) no me diría si la parte superior de la barra de navegación alguna vez se desplazó a la parte superior de la página visible (nuevamente, como se informó en la consola, simplemente permanecieron los mismos números mientras se desplazaba ocurrió).
Solución
La solución para mí fue utilizar
window.visualViewport.pageTop
El valor de la propiedad pageTop refleja la sección visible de la pantalla, lo que me permite rastrear dónde está un elemento en referencia a los límites del área visible.
Probablemente sea innecesario decir que cada vez que estoy tratando con el desplazamiento espero usar esta solución para responder programáticamente al movimiento de los elementos que se desplazan.
Espero que ayude a alguien más.
NOTA IMPORTANTE: Esto parece funcionar en Chrome y Opera actualmente y definitivamente no en Firefox (6-2018) ... hasta que Firefox admita visualViewport, recomiendo NO usar este método (y espero que lo hagan pronto ... hace mucho) más sentido que el resto).
ACTUALIZACIÓN:
solo una nota con respecto a esta solución. Si bien todavía encuentro que lo que descubrí es muy valioso para situaciones en las que "... responde programáticamente al movimiento de los elementos que se desplazan". es aplicable. La mejor solución para el problema que tuve fue usar CSS para establecer la posición: pegajosoen el elemento Usando sticky puede hacer que un elemento permanezca en la parte superior sin usar javascript (NOTA: hay veces que esto no funcionará de manera tan efectiva como cambiar el elemento a fijo pero para la mayoría de los usos el enfoque adhesivo probablemente sea superior)
ACTUALIZACIÓN01:
Entonces me di cuenta de que para una página diferente tenía un requisito en el que necesitaba detectar la posición de un elemento en una configuración de desplazamiento levemente compleja (paralaje más elementos que se desplazan como parte de un mensaje). Me di cuenta en ese escenario que lo siguiente proporcionó el valor que utilicé para determinar cuándo hacer algo:
es muy probable que esto esté en la parte superior de tantas respuestas cuando hace clic en activo para ordenar las respuestas
lucchi
@lucchi: D bueno, supongo que podría eliminar el texto en la parte superior ... aunque acabo de pasar por este tema nuevamente y me di cuenta de que había encontrado una mejor solución para mi propio problema ... aunque mi respuesta es más nota al pie de las respuestas más completas. Sospecho que mis requisitos no eran tan comunes como para que las otras respuestas no me funcionaran.
MER
1
Aprecio tu respuesta de todos modos, fue solo para decirte que cualquiera que esté dispuesto sabrá que escribiste algo nuevo. No estás solo ...
lucchi 01 de
5
Lo hice así, por lo que era compatible con los navegadores antiguos.
// For really old browser's or incompatible onesfunction getOffsetSum(elem){var top =0,
left =0,
bottom =0,
right =0var width = elem.offsetWidth;var height = elem.offsetHeight;while(elem){
top += elem.offsetTop;
left += elem.offsetLeft;
elem = elem.offsetParent;}
right = left + width;
bottom = top + height;return{
top: top,
left: left,
bottom: bottom,
right: right,}}function getOffsetRect(elem){var box = elem.getBoundingClientRect();var body = document.body;var docElem = document.documentElement;var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;var clientTop = docElem.clientTop;var clientLeft = docElem.clientLeft;var top = box.top + scrollTop - clientTop;var left = box.left + scrollLeft - clientLeft;var bottom = top +(box.bottom - box.top);var right = left +(box.right - box.left);return{
top:Math.round(top),
left:Math.round(left),
bottom:Math.round(bottom),
right:Math.round(right),}}function getOffset(elem){if(elem){if(elem.getBoundingClientRect){return getOffsetRect(elem);}else{// old browserreturn getOffsetSum(elem);}}elsereturnnull;}
Utilicé con éxito la solución de Andy E para posicionar un modo de arranque 2 dependiendo de en qué enlace de una fila de la tabla haga clic el usuario. La página es una página de Tapestry 5 y javascript se importa a continuación en la clase de página java.
Este código js me ayudó, tengo una aplicación de formularios web antigua que usa múltiples marcadores de posición para inyectar páginas .aspx y no pude encontrar la manera de agregar Child () de un cuadro emergente que estaba creando para ingresarlo a la ventana gráfica porque todo el árbol DOM está loco con los múltiples marcadores de posición y marcado incorrecto. Usar el body.getBoundingClientRect () y luego usar su parte superior en posicionamiento era lo que necesitaba. Gracias.
Brad Martin
1
Después de mucha investigación y pruebas, esto parece funcionar
function getPosition(e){var isNotFirefox =(navigator.userAgent.toLowerCase().indexOf('firefox')==-1);var x =0, y =0;while(e){
x += e.offsetLeft - e.scrollLeft +(isNotFirefox ? e.clientLeft :0);
y += e.offsetTop - e.scrollTop +(isNotFirefox ? e.clientTop :0);
e = e.offsetParent;}return{ x: x + window.scrollX, y: y + window.scrollY };}
Dado que diferentes navegadores representan bordes, relleno, margen, etc. de manera diferente Escribí una pequeña función para recuperar las posiciones superior e izquierda de un elemento específico en cada elemento raíz que desee en una dimensión precisa:
Obtener posición de div con respecto a izquierda y arriba
var elm = $('#div_id');//get the divvar posY_top = elm.offset().top;//get the position from topvar posX_left = elm.offset().left;//get the position from left
Voté a la baja porque la parte inferior y la derecha no son propiedades de offset ()
MacroMan
@MacroMan, respeto su decisión, pero ya he explicado en el texto que "el código inferior y derecho no se ha probado". Además, actualizaré mi código muy pronto.
Vishal
Creo que es el.offsetTopy el.offsetLeft(el PO no dice nada acerca de jQuery ... No estoy seguro de por qué su respuesta utiliza jQuery tampoco ...)
Respuestas:
El enfoque correcto es usar
element.getBoundingClientRect()
:Internet Explorer lo ha respaldado desde que es probable que le importe y finalmente se estandarizó en las vistas CSSOM . Todos los demás navegadores lo adoptaron hace mucho tiempo .
Algunos navegadores también devuelven propiedades de alto y ancho, aunque esto no es estándar. Si le preocupa la compatibilidad del navegador anterior, consulte las revisiones de esta respuesta para una implementación degradante optimizada.
Los valores devueltos por
element.getBoundingClientRect()
son relativos a la ventana gráfica. Si lo necesita en relación con otro elemento, simplemente reste un rectángulo del otro:fuente
<body>
embargo, vale la pena señalar que los reinicios de CSS eliminan el margen .element.getBoundingClientRect().top
no devuelve el desplazamiento superior correcto en el caso de unposition: fixed
elemento en iOS (iPhone 8) si contiene un elemento de entrada enfocado y el teclado virtual se ha deslizado hacia arriba. Por ejemplo, si el desplazamiento real desde la parte superior de la ventana es de 200 px, lo informaría como 420 px, donde 220 px es la altura del teclado virtual. Si configura los elementosposition: absolute
y los coloca en la misma posición que si fueran fijos, obtendrá el 200px correcto. No sé una solución para esto.Las bibliotecas hacen todo lo posible para obtener compensaciones precisas para un elemento.
Aquí hay una función simple que hace el trabajo en todas las circunstancias que he probado.
fuente
Esto funcionó para mí (modificado de la respuesta más votada):
Usando esto podemos llamar
o
fuente
div
cuyo centrado usando CSStop:50%, left:50%; transform:translate(-50%, -50%);
... excelente. De acuerdo con la pregunta de @ScottBiggs. Lógico es buscar la simplicidad.rect
el uso devar
,let
oconst
. De lo contrario, se define comowindow.rect
.left: rect.left + window.scrollX + (rect.width / 2), top: rect.top + window.scrollY + (rect.height / 2)
devolverá la posición media de un elementoSi desea que se haga solo en javascript , aquí hay algunos liners que usan
getBoundingClientRect()
La primera línea devolverá
offsetTop
decir Y en relación con el documento. La segunda línea devolveráoffsetLeft
decir X en relación con el documento.getBoundingClientRect()
es una función de JavaScript que devuelve la posición del elemento en relación con la ventana gráfica de la ventana.fuente
Los elementos HTML en la mayoría de los navegadores tendrán: -
Estos especifican la posición del elemento en relación con su padre más cercano que tiene diseño. A menudo se puede acceder a este padre mediante la propiedad offsetParent.
IE y FF3 tienen
Estas propiedades son menos comunes, especifican una posición de los elementos con el área del cliente principal (el área acolchada es parte del área del cliente pero el borde y el margen no lo son).
fuente
Si la página incluye, al menos, cualquier "DIV", la función dada por meouw arroja el valor "Y" más allá de los límites actuales de la página. Para encontrar la posición exacta, debe manejar tanto offsetParent's como parentNode's.
Pruebe el código que figura a continuación (se verifica para FF2):
fuente
Puede agregar dos propiedades para
Element.prototype
obtener la parte superior / izquierda de cualquier elemento.Esto se llama así:
Aquí hay una demostración que compara los resultados con los de jQuery
offset().top
y.left
: http://jsfiddle.net/ThinkingStiff/3G7EZ/fuente
Element.prototype
generalmente se considera una mala idea . Conduce a un código realmente difícil de mantener. Además, este código no tiene en cuenta el desplazamiento.Para recuperar la posición relativa a la página de manera eficiente y sin usar una función recursiva: (también incluye IE)
fuente
¿Qué tal algo como esto? Al pasar la ID del elemento y devolverá la izquierda o la parte superior, también podemos combinarlos:
1) encontrar a la izquierda
2) encontrar la parte superior
o 3) encontrar izquierda y arriba juntos
fuente
Es posible que le sirva mejor utilizando un marco de JavaScript, que tiene funciones para devolver dicha información (¡y mucho más!) De forma independiente del navegador. Aquí hay algunos:
Con estos marcos, puede hacer algo como:
$('id-of-img').top
obtener la coordenada y-pixel de la imagen.fuente
jQuery .offset () obtendrá las coordenadas actuales del primer elemento, o establecerá las coordenadas de cada elemento, en el conjunto de elementos coincidentes, en relación con el documento.
fuente
Tomé la respuesta de @ meouw, agregué el clientLeft que permite el borde y luego creé tres versiones:
getAbsoluteOffsetFromBody - similar a @ meouw's, esto obtiene la posición absoluta en relación con el cuerpo o el elemento html del documento (dependiendo del modo peculiaridades)
getAbsoluteOffsetFromGivenElement: devuelve la posición absoluta en relación con el elemento dado (relativeEl). Tenga en cuenta que el elemento dado debe contener el elemento el, o esto se comportará igual que getAbsoluteOffsetFromBody. Esto es útil si tiene dos elementos contenidos dentro de otro elemento (conocido) (opcionalmente, varios nodos en el árbol de nodos) y desea colocarlos en la misma posición.
getAbsoluteOffsetFromRelative: devuelve la posición absoluta relativa al primer elemento padre con position: relative. Esto es similar a getAbsoluteOffsetFromGivenElement, por la misma razón, pero solo irá hasta el primer elemento coincidente.
Si todavía tiene problemas, particularmente en relación con el desplazamiento, puede intentar mirar http://www.greywyvern.com/?post=331 . Noté al menos una pieza de código cuestionable en getStyle que debería estar bien asumiendo que los navegadores se comporten bien , pero no he probado el resto en absoluto.
fuente
si usa jQuery, el complemento de dimensiones es excelente y le permite especificar exactamente lo que desea.
p.ej
Posición relativa, posición absoluta, posición absoluta sin relleno, con relleno ...
Continúa, digamos que hay mucho que puedes hacer con él.
Además, la ventaja de usar jQuery es su tamaño de archivo ligero y fácil de usar, no volverá a JavaScript sin él después.
fuente
Este es el mejor código que he logrado crear (también funciona en iframes, a diferencia del desplazamiento de jQuery ()). Parece que webkit tiene un comportamiento un poco diferente.
Basado en el comentario de meouw:
fuente
jQuery
deberá usar$.browser.webkit
; Tendrás que jugarnavigator.userAgent
para hacer lo mismo con pureJavaScript
.Si está utilizando jQuery, esta podría ser una solución simple:
fuente
Diferencia entre pequeño y pequeño
Mira un ejemplo de coordenadas: http://javascript.info/tutorial/coordinates
fuente
<svg>
elementos, por ejemplo, no tienenoffsetLeft
,offsetTop
yoffsetParent
propiedades.DIV
oIMG
noSVG
. Ver "Buscar un ejemplo de coordenadas"? puede encontrar el objeto svg es llamar a la posición getOffsetRect , intente y dependa del trabajo del objeto.El enfoque más limpio que he encontrado es una versión simplificada de la técnica utilizada por jQuery
offset
. Similar a algunas de las otras respuestas con las que comienzagetBoundingClientRect
; luego usa elwindow
y eldocumentElement
para ajustar la posición de desplazamiento, así como elementos como el margen enbody
(a menudo el predeterminado).Mostrar fragmento de código
fuente
Si bien es muy probable que esto se pierda al final de tantas respuestas, las mejores soluciones aquí no me funcionaron.
Por lo que pude ver, ninguna de las otras respuestas habría ayudado.
Situación :
en una página HTML5 tenía un menú que era un elemento de navegación dentro de un encabezado (no EL encabezado sino un encabezado en otro elemento).
Quería que la navegación se mantuviera en la parte superior una vez que un usuario se desplazara hacia ella, pero antes de esto, el encabezado estaba en una posición absoluta (para que pudiera superponer algo más).
Las soluciones anteriores nunca activaron un cambio porque .offsetTop no iba a cambiar ya que este era un elemento de posición absoluta. Además, la propiedad .scrollTop era simplemente la parte superior del elemento más superior ... es decir 0 y siempre sería 0.
Cualquier prueba que realicé utilizando estos dos (y lo mismo con los resultados de getBoundingClientRect) no me diría si la parte superior de la barra de navegación alguna vez se desplazó a la parte superior de la página visible (nuevamente, como se informó en la consola, simplemente permanecieron los mismos números mientras se desplazaba ocurrió).
Solución
La solución para mí fue utilizar
El valor de la propiedad pageTop refleja la sección visible de la pantalla, lo que me permite rastrear dónde está un elemento en referencia a los límites del área visible.
Probablemente sea innecesario decir que cada vez que estoy tratando con el desplazamiento espero usar esta solución para responder programáticamente al movimiento de los elementos que se desplazan.
Espero que ayude a alguien más.
NOTA IMPORTANTE: Esto parece funcionar en Chrome y Opera actualmente y definitivamente no en Firefox (6-2018) ... hasta que Firefox admita visualViewport, recomiendo NO usar este método (y espero que lo hagan pronto ... hace mucho) más sentido que el resto).
ACTUALIZACIÓN:
solo una nota con respecto a esta solución.
Si bien todavía encuentro que lo que descubrí es muy valioso para situaciones en las que "... responde programáticamente al movimiento de los elementos que se desplazan". es aplicable. La mejor solución para el problema que tuve fue usar CSS para establecer la posición: pegajosoen el elemento Usando sticky puede hacer que un elemento permanezca en la parte superior sin usar javascript (NOTA: hay veces que esto no funcionará de manera tan efectiva como cambiar el elemento a fijo pero para la mayoría de los usos el enfoque adhesivo probablemente sea superior)
ACTUALIZACIÓN01:
Entonces me di cuenta de que para una página diferente tenía un requisito en el que necesitaba detectar la posición de un elemento en una configuración de desplazamiento levemente compleja (paralaje más elementos que se desplazan como parte de un mensaje). Me di cuenta en ese escenario que lo siguiente proporcionó el valor que utilicé para determinar cuándo hacer algo:
Espero que esta respuesta sea más útil ahora.
fuente
Lo hice así, por lo que era compatible con los navegadores antiguos.
Más información sobre las coordenadas en JavaScript aquí: http://javascript.info/tutorial/coordinates
fuente
Para obtener el desplazamiento total de un elemento, puede resumir recursivamente todos los desplazamientos principales:
Con esta función de utilidad, el desplazamiento superior total de un elemento dom es:
fuente
Gracias ThinkingStiff por la respuesta , esta es solo otra versión de la misma.
fuente
Utilicé con éxito la solución de Andy E para posicionar un modo de arranque 2 dependiendo de en qué enlace de una fila de la tabla haga clic el usuario. La página es una página de Tapestry 5 y javascript se importa a continuación en la clase de página java.
javascript:
}
Mi código modal:
El enlace en el bucle:
Y el código de Java en la clase de página:
Espero que esto ayude a alguien, esta publicación ayudó.
fuente
Después de mucha investigación y pruebas, esto parece funcionar
ver http://jsbin.com/xuvovalifo/edit?html,js,output
fuente
Solo pensé en tirar esto por ahí también.
No he podido probarlo en navegadores antiguos, pero funciona en el último de los 3 principales :).
fuente
Dado que diferentes navegadores representan bordes, relleno, margen, etc. de manera diferente Escribí una pequeña función para recuperar las posiciones superior e izquierda de un elemento específico en cada elemento raíz que desee en una dimensión precisa:
Para recuperar la posición izquierda debe regresar:
fuente
fuente
el.offsetTop
yel.offsetLeft
(el PO no dice nada acerca de jQuery ... No estoy seguro de por qué su respuesta utiliza jQuery tampoco ...)