jQuery obtiene la ubicación de un elemento relativo a la ventana

168

Dado un ID de DOM HTML, ¿cómo obtener la posición de un elemento en relación con la ventana en JavaScript / JQuery? Esto no es lo mismo en relación con el documento ni el elemento primario desplazado, ya que el elemento puede estar dentro de un iframe u otros elementos. Necesito obtener la ubicación de la pantalla del rectángulo del elemento (como en posición y dimensión) como se muestra actualmente. Los valores negativos son aceptables si el elemento está actualmente fuera de la pantalla (se ha desplazado hacia afuera).

Esto es para una aplicación iPad (WebKit / WebView). Cada vez que el usuario toca un enlace especial en un UIWebView, se supone que debo abrir una vista emergente que muestra más información sobre el enlace. La vista emergente debe mostrar una flecha que apunte a la parte de la pantalla que la invoca.

adib
fuente

Respuestas:

264

Inicialmente, tome la posición .offset del elemento y calcule su posición relativa con respecto a la ventana

Consulte :
1. desplazamiento
2. desplazamiento
3. desplazamiento arriba

Puedes probarlo en este violín

Seguir unas pocas líneas de código explica cómo se puede resolver esto

cuando se realiza el evento .scroll , calculamos la posición relativa del elemento con respecto al objeto de ventana

$(window).scroll(function () {
    console.log(eTop - $(window).scrollTop());
});

cuando se realiza el desplazamiento en el navegador, llamamos a la función del controlador de eventos anterior

fragmento de código


function log(txt) {
  $("#log").html("location : <b>" + txt + "</b> px")
}

$(function() {
  var eTop = $('#element').offset().top; //get the offset top of the element
  log(eTop - $(window).scrollTop()); //position of the ele w.r.t window

  $(window).scroll(function() { //when window is scrolled
    log(eTop - $(window).scrollTop());
  });
});
#element {
  margin: 140px;
  text-align: center;
  padding: 5px;
  width: 200px;
  height: 200px;
  border: 1px solid #0099f9;
  border-radius: 3px;
  background: #444;
  color: #0099d9;
  opacity: 0.6;
}
#log {
  position: fixed;
  top: 40px;
  left: 40px;
  color: #333;
}
#scroll {
  position: fixed;
  bottom: 10px;
  right: 10px;
  border: 1px solid #000;
  border-radius: 2px;
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="log"></div>

<div id="element">Hello
  <hr>World</div>
<div id="scroll">Scroll Down</div>

jterry
fuente
1
Gracias por el guion. Esto parece funcionar en el escritorio, pero no funciona en el iPad. Parece que $ (window) .scrollTop () y $ (window) .scrollLeft () no se actualizan en el iPad. Puede probar mi versión a través de jsbin.com/ogiwu4/5
adib
2
No se actualizan en el iPad porque la ventana en sí no se desplaza, el usuario se desplaza dentro de la ventana. Ese es el caso de un sitio web básico de todos modos, no estoy seguro acerca de uno que esté dirigido a dispositivos móviles, probablemente tenga más opciones allí.
eselk
Esto debería fallar cuando un elemento está dentro de otro elemento desplazable, e. gramo. <div>. Solo tiene en cuenta el desplazamiento del documento, pero no el desplazamiento del otro elemento.
ygoe
71

Prueba el cuadro delimitador. Es sencillo:

var leftPos  = $("#element")[0].getBoundingClientRect().left   + $(window)['scrollLeft']();
var rightPos = $("#element")[0].getBoundingClientRect().right  + $(window)['scrollLeft']();
var topPos   = $("#element")[0].getBoundingClientRect().top    + $(window)['scrollTop']();
var bottomPos= $("#element")[0].getBoundingClientRect().bottom + $(window)['scrollTop']();
martillo programador
fuente
77
getBoundingClientRect () es la respuesta a este problema. Gracias prograhammer.
Vlad Lego
1
Esto funcionó bien. Solo tenía que incluir un código para arreglar mi desplazamiento, además de scrollLetf y scrollTop: topPos = topPos - $ (ventana) .scrollTop (); leftPos = leftPos - $ (ventana) .scrollLeft (); rightPos = rightPos - $ (ventana) .scrollTop (); bottomPos = bottomPos - $ (ventana) .scrollLeft ();
Cesar
1
el día en que la gente va a aprender a envolver las cosas en un buen método útil
mmm
@Noldorin El soporte en IE / Edge me parece bien: caniuse.com/#feat=getboundingclientrect
prograhammer
1
@ programador Mi mal, tienes razón. Leí esto en algún sitio web y tomé su palabra al pie de la letra ... resulta que estaba mal (o al menos no funciona en el antiguo IE).
Noldorin
6
function getWindowRelativeOffset(parentWindow, elem) {
        var offset = {
            left : 0,
            top : 0
        };
        // relative to the target field's document
        offset.left = elem.getBoundingClientRect().left;
        offset.top = elem.getBoundingClientRect().top;
        // now we will calculate according to the current document, this current
        // document might be same as the document of target field or it may be
        // parent of the document of the target field
        var childWindow = elem.document.frames.window;
        while (childWindow != parentWindow) {
            offset.left = offset.left + childWindow.frameElement.getBoundingClientRect().left;
            offset.top = offset.top + childWindow.frameElement.getBoundingClientRect().top;
            childWindow = childWindow.parent;
        }
        return offset;
    };

puedes llamarlo asi

getWindowRelativeOffset(top, inputElement);

Me concentro en IE solo según mis requisitos, pero se puede hacer algo similar para otros navegadores

Imran Ansari
fuente
4

Esto suena más como si quisiera una información sobre herramientas para el enlace seleccionado. Hay muchas informaciones sobre herramientas de jQuery, pruebe jQuery qTip . Tiene muchas opciones y es fácil cambiar los estilos.

De lo contrario, si desea hacerlo usted mismo, puede usar jQuery .position(). Más información sobre .position()está en http://api.jquery.com/position/

$("#element").position(); devolverá la posición actual de un elemento en relación con el elemento primario desplazado.

También está el jQuery .offset (); que devolverá la posición relativa al documento.

jhanifen
fuente
2
No es realmente una información sobre herramientas, sino abrir un widget de interfaz de usuario nativo para agregar anotaciones.
adib
1
    function trbl(e, relative) {
            var r = $(e).get(0).getBoundingClientRect(); relative = $(relative);

            return {
                    t : r.top    + relative['scrollTop'] (),
                    r : r.right  + relative['scrollLeft'](),
                    b : r.bottom + relative['scrollTop'] (),
                    l : r.left   + relative['scrollLeft']() 

            }
    }

    // Example
    trbl(e, window);
mmm
fuente
1

Intente esto para obtener la ubicación de un elemento relativo a la ventana.

        $("button").click(function(){
            var offset = $("#simplebox").offset();
            alert("Current position of the box is: (left: " + offset.left + ", top: " + offset.top + ")");
        });
    #simplebox{
        width:150px;
        height:100px;
        background: #FBBC09;
        margin: 150px 100px;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button">Get Box Position</button>
    <p><strong>Note:</strong> Play with the value of margin property to see how the jQuery offest() method works.</p>
    <div id="simplebox"></div>

Ver más @ Obtenga la posición de un elemento relativo al documento con jQuery

Ketan Savaliya
fuente