jQuery obtém a localização de um elemento em relação à janela

168

Dado um DOM HTML, como obter a posição de um elemento em relação à janela em JavaScript / JQuery? Não é o mesmo que relativo ao documento nem pai-offset, pois o elemento pode estar dentro de um iframe ou de alguns outros elementos. Preciso obter a localização da tela do retângulo do elemento (como em posição e dimensão), pois ele está sendo exibido no momento. Valores negativos são aceitáveis ​​se o elemento estiver atualmente fora da tela (foi rolado para fora).

Isto é para um aplicativo para iPad (WebKit / WebView). Sempre que o usuário toca em um link especial em um UIWebView, devo abrir uma exibição popover que exibe mais informações sobre o link. A visualização popover precisa exibir uma seta que aponte para a parte da tela que a chama.

adib
fonte

Respostas:

264

Inicialmente, agarre a posição .offset do elemento e calcule sua posição relativa em relação à janela

Consulte :
1. deslocamento
2. rolagem
3. scrollTop

Você pode tentar este violino

Seguir algumas linhas de código explica como isso pode ser resolvido

quando o evento .scroll é realizado, calculamos a posição relativa do elemento em relação ao objeto da janela

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

quando a rolagem é realizada no navegador, chamamos a função manipulador de eventos acima

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
fonte
1
Obrigado pelo script. Isso parece funcionar na área de trabalho, mas não no iPad. Parece que $ (window) .scrollTop () e $ (window) .scrollLeft () não são atualizados no iPad. Você pode experimentar minha versão via jsbin.com/ogiwu4/5
adib
2
Eles não são atualizados no iPad porque a janela em si não está rolando - o usuário está rolando dentro da janela. De qualquer maneira, esse é o caso de um site básico, que não tem certeza de um que tenha como alvo dispositivos móveis, provavelmente tem mais opções lá.
Eselk # 22/13
Isso deve falhar quando um elemento está dentro de outro elemento rolável, e. g. <div>. Você considera apenas a rolagem do documento, mas não a rolagem do outro elemento.
ygoe
71

Experimente a caixa delimitadora. É simples:

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']();
programador
fonte
7
getBoundingClientRect () é a resposta para esse problema. Obrigado programador.
Vlad Lego
1
isso funcionou bem. Eu apenas precisei incluir algum código para corrigir meu scroll, além dos scrollLetf e scrollTop: topPos = topPos - $ (window) .scrollTop (); leftPos = leftPos - $ (janela) .scrollLeft (); rightPos = rightPos - $ (janela) .scrollTop (); bottomPos = bottomPos - $ (janela) .scrollLeft ();
Cesar
1
o dia em que as pessoas vão aprender a embrulhar as coisas em um método útil agradável
mmm
@Noldorin O apoio no IE / Borda parece ser bom para mim: caniuse.com/#feat=getboundingclientrect
prograhammer
1
@prograhammer Meu mal, você está certo. Eu li isso em algum site e tomei sua palavra pelo valor nominal ... Acontece que estava errado (ou pelo menos não funciona no IE antigo).
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;
    };

você pode chamar assim

getWindowRelativeOffset(top, inputElement);

Eu me concentro no IE apenas conforme minha exigência, mas o mesmo pode ser feito para outros navegadores

Imran Ansari
fonte
4

Parece mais que você deseja uma dica de ferramenta para o link selecionado. Existem muitas dicas de ferramentas do jQuery, experimente o jQuery qTip . Tem muitas opções e é fácil mudar os estilos.

Caso contrário, se você quiser fazer isso sozinho, poderá usar o jQuery .position(). Mais informações sobre .position()estão em http://api.jquery.com/position/

$("#element").position(); retornará a posição atual de um elemento em relação ao pai de deslocamento.

Há também o jQuery .offset (); que retornará a posição relativa ao documento.

jhanifen
fonte
2
Não é realmente uma dica de ferramenta, mas abrir um widget de interface do usuário nativo para adicionar anotações.
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
fonte
1

Tente isso para obter a localização de um elemento em relação à janela.

        $("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>

Veja mais @ Obter a posição de um elemento em relação ao documento com jQuery

Ketan Savaliya
fonte