javascript - obtener - Recuperar la posición(X, Y) de un elemento HTML




obtener contenido de un div javascript (16)

Quiero saber cómo obtener la posición X e Y de elementos HTML como img y div en JavaScript.


Obtener la posición de div con respecto a la izquierda y la parte superior

  var elm = $('#div_id');  //get the div
  var posY_top = elm.offset().top;  //get the position from top
  var posX_left = elm.offset().left; //get the position from left 

¿Qué tal algo como esto? Al pasar el 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 top

function findTop(element) {
  var rec = document.getElementById(element).getBoundingClientRect();
  return rec.top + window.scrollY;
} //call it like findTop('#header');

o 3) encontrar a la 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');

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

consulte http://jsbin.com/xuvovalifo/edit?html,js,output


Diferencia entre pequeño y pequeño.

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

Mira un ejemplo de coordenadas: http://javascript.info/tutorial/coordinates


El enfoque más limpio que he encontrado es una versión simplificada de la técnica utilizada por la offset de jQuery. Similar a algunas de las otras respuestas, comienza con getBoundingClientRect ; luego utiliza la window y el elemento de documentElement para ajustar la posición de desplazamiento, así como elementos como el margen en el body (a menudo el valor predeterminado).

var rect = el.getBoundingClientRect();
var docEl = document.documentElement;

var rectTop = rect.top + window.pageYOffset - docEl.clientTop;
var rectLeft = rect.left + window.pageXOffset - docEl.clientLeft;

var els = document.getElementsByTagName("div");
var docEl = document.documentElement;

for (var i = 0; i < els.length; i++) {

  var rect = els[i].getBoundingClientRect();

  var rectTop = rect.top + window.pageYOffset - docEl.clientTop;
  var rectLeft = rect.left + window.pageXOffset - docEl.clientLeft;

  els[i].innerHTML = "<b>" + rectLeft + ", " + rectTop + "</b>";
}
div {
  width: 100px;
  height: 100px;
  background-color: red;
  border: 1px solid black;
}
#rel {
  position: relative;
  left: 10px;
  top: 10px;
}
#abs {
  position: absolute;
  top: 250px;
  left: 250px;
}
<div id="rel"></div>
<div id="abs"></div>
<div></div>


Es posible que le sirvan mejor utilizando un marco de JavaScript, que tiene funciones para devolver dicha información (¡y mucho más!) De una manera independiente del navegador. Aquí hay algunos:

Con estos marcos, podrías hacer algo como: $('id-of-img').top para obtener la coordenada y píxel de la imagen.


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

Usando esto podemos llamar

getOffset(element).left

o

getOffset(element).top

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; 

Los elementos HTML en la mayoría de los navegadores tendrán: -

offsetLeft
offsetTop

Estos especifican la posición del elemento relativo a su padre más cercano que tiene diseño. A este padre a menudo se puede acceder desde la propiedad offsetParent.

IE y FF3 tienen

clientLeft
clientTop

Estas propiedades son menos comunes, especifican una posición de elementos con su área de cliente principal (el área rellenada es parte del área de cliente pero el borde y el margen no lo son).


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 y
var 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;

Si bien es muy probable que esto se pierda al final de tantas respuestas, las mejores soluciones aquí no funcionaron para mí.
Por lo que pude ver, ninguna de las otras respuestas me habría ayudado.

Situacion
En una página HTML5 tenía un menú que era un elemento de navegación dentro de un encabezado (no el encabezado EL sino un encabezado en otro elemento).
Quería que la navegación se mantuviera en la parte superior una vez que el 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 posicionado absoluto. 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ó hasta la parte superior de la página visible (nuevamente, como se informó en la consola, simplemente mantuvieron los mismos números mientras se desplazaban) 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, por lo que me permite rastrear dónde se encuentra un elemento en referencia a los límites del área visible.

Probablemente no sea necesario decirlo, en cualquier momento en el que tenga que ver con el desplazamiento, espero usar esta solución para responder de manera programática al movimiento de los elementos que se están desplazando.
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).


ACTUALIZAR:
Sólo una nota con respecto a esta solución.
Si bien todavía encuentro lo que descubrí que es muy valioso para situaciones en las que "... responda de manera programática al movimiento de elementos que se están desplazando". es aplicable. La mejor solución para el problema que tuve fue usar CSS para establecer la posición: pegado en el elemento. Si usa el adhesivo, puede hacer que un elemento permanezca en la parte superior sin usar javascript (NOTA: hay veces que esto no funcionará tan eficazmente como cambiar el elemento a fijo, pero para la mayoría de los usos, el enfoque pegajoso probablemente sea superior)

ACTUALIZACIÓN01:
Así que 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 ligeramente compleja (paralaje más elementos que se desplazan como parte de un mensaje). Me di cuenta en ese escenario que lo siguiente proporcionaba el valor que utilicé para determinar cuándo hacer algo:

  let bodyElement = document.getElementsByTagName('body')[0];
  let elementToTrack = bodyElement.querySelector('.trackme');
  trackedObjPos = elementToTrack.getBoundingClientRect().top;
  if(trackedObjPos > 264)
  {
    bodyElement.style.cssText = '';
  }

Espero que esta respuesta sea más útil ahora.


Si está utilizando jQuery, esta podría ser una solución simple:

<script>
  var el = $("#element");
  var position = el.position();
  console.log( "left: " + position.left + ", top: " + position.top );
</script>

Si quieres hacerlo solo en javascript . Que aquí están los trazadores de líneas . Es más simple y fácil de usar getBoundingClientRect ()

window.scrollX + document.querySelector('#elementId').getBoundingClientRect().left // X

window.scrollY + document.querySelector('#elementId').getBoundingClientRect().top // Y

La primera línea devolverá offsetLeft decir X en relación con el documento

Y la segunda línea devolverá offsetTop decir Y en relación con el documento

element.getBoundingClientRect() es una función javascript que devuelve la posición del elemento en relación con la ventana element.getBoundingClientRect() .


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 ...

Sigue, digamos que hay mucho que puedes hacer con eso.

Además, la ventaja de usar jQuery es su tamaño de archivo ligero y su fácil uso, no volverá a JavaScript sin él después.


Tomé la respuesta de @ meouw, la agregué en el clientLeft que permite el borde y luego creé tres versiones:

getAbsoluteOffsetFromBody - similar a @ meouw's, obtiene la posición absoluta con respecto al cuerpo o elemento html del documento (según el modo de peculiaridades)

getAbsoluteOffsetFromGivenElement: devuelve la posición absoluta relativa al elemento dado (relativeEl). Tenga en cuenta que el elemento dado debe contener el elemento el, o se comportará de la misma manera que getAbsoluteOffsetFromBody. Esto es útil si tiene dos elementos contenidos en otro elemento (conocido) (opcionalmente, varios nodos en el árbol de nodos) y desea que estén en la misma posición.

getAbsoluteOffsetFromRelative: devuelve la posición absoluta en relación con el primer elemento padre con position: relative. Esto es similar a getAbsoluteOffsetFromGivenElement, por el mismo motivo, pero solo irá tan lejos como el primer elemento coincidente.

getAbsoluteOffsetFromBody = function( el )
{   // finds the offset of el from the body or html element
    var _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 relativeEl
    var _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: relative
    var _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 aún tiene problemas, especialmente en relación con el desplazamiento, puede intentar visitar http://www.greywyvern.com/?post=331 : noté al menos una pieza de código cuestionable en getStyle que debería estar bien suponiendo que los navegadores se comporten , pero no he probado el resto en absoluto.


Usé con éxito la solución de Andy E para posicionar un modo bootstrap 2 dependiendo del enlace en la fila de la tabla en el que un usuario hace clic. 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:

function setLinkPosition(clientId){
var bodyRect = document.body.getBoundingClientRect(),
elemRect = clientId.getBoundingClientRect(),
offset   = elemRect.top - bodyRect.top;
offset   = offset + 20;
$('#serviceLineModal').css("top", offset);

}

Mi código modal:

<div id="serviceLineModal" class="modal hide fade add-absolute-position" data-backdrop="static" 
 tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="top:50%;">
<div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
    <h3 id="myModalLabel">Modal header</h3>
</div>

<div class="modal-body">
    <t:zone t:id="modalZone" id="modalZone">
        <p>You selected service line number: ${serviceLineNumberSelected}</p>
    </t:zone>
</div>

<div class="modal-footer">
    <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
    <!-- <button class="btn btn-primary">Save changes</button> -->
</div>

El enlace en el bucle:

<t:loop source="servicesToDisplay" value="service" encoder="encoder">
<tr style="border-right: 1px solid black;">       
    <td style="white-space:nowrap;" class="add-padding-left-and-right no-border"> 
        <a t:type="eventLink" t:event="serviceLineNumberSelected" t:context="service.serviceLineNumber" 
            t:zone="pageZone" t:clientId="modalLink${service.serviceLineNumber}"
            onmouseover="setLinkPosition(this);">
            <i class="icon-chevron-down"></i> <!-- ${service.serviceLineNumber} -->
        </a>
    </td>

Y el código java en la clase de la página:

void onServiceLineNumberSelected(String number){
    checkForNullSession();
    serviceLineNumberSelected = number;
    addOpenServiceLineDialogCommand();
    ajaxResponseRenderer.addRender(modalZone);
}

protected void addOpenServiceLineDialogCommand() {
    ajaxResponseRenderer.addCallback(new JavaScriptCallback() {
        @Override
        public void run(JavaScriptSupport javascriptSupport) {
            javascriptSupport.addScript("$('#serviceLineModal').modal('show');");
        }
    });
}

Espero que esto ayude a alguien, este post ayudó.







position