eu estava usando essas 7 linhas de código que funcionam em todos os navegadores com discrepâncias em ie5,6,7 (não me lembrava de ter nenhum problema ... pode ser o tipo de documento) ... quirksmode.org/js/findpos. html e eu tenho usado muito por muitos anos. pode ser que alguém possa apontar as falhas, se houver.
precisa saber é o seguinte
98
@AnthonyWJones, suponho que você precisasse do prazer pedante, mas é óbvio, como sempre é quando não especificado, que o OP se refere ao caso mais geral ou às coordenadas da janela do navegador.
Motes 26/05
7
@Mote, não, não é tão óbvio. Deixe de lado a inferência, a subjetividade e os falsos axiomas. Pode ser relativo à viewport ou ao topo da página (também conhecido como document.documentElement).
Andre Figueiredo
15
A padronização para o mais geral não é inferência, é a progressão lógica, portanto seria relativa à janela ou "topo da página" pode ser o termo que você coloca. Na teoria dos jogos, é codificado como um conceito chamado ponto de Schelling. Certifique-se de especificar quando não se refere ao caso mais geral.
var rect = element.getBoundingClientRect();
console.log(rect.top, rect.right, rect.bottom, rect.left);
O Internet Explorer oferece suporte a isso desde que você provavelmente se preocupe e, finalmente, foi padronizado nas Visualizações CSSOM . Todos os outros navegadores o adotaram há muito tempo .
Alguns navegadores também retornam propriedades de altura e largura, embora isso não seja padrão. Se você está preocupado com a compatibilidade do navegador mais antigo, verifique as revisões desta resposta para obter uma implementação degradada otimizada.
Os valores retornados por element.getBoundingClientRect()são relativos à viewport. Se você precisar dele em relação a outro elemento, basta subtrair um retângulo do outro:
var bodyRect = document.body.getBoundingClientRect(),
elemRect = element.getBoundingClientRect(),
offset = elemRect.top - bodyRect.top;
alert('Element is '+ offset +' vertical pixels from <body>');
Não funciona ... são 8 pixels na vertical e na horizontal, devido à margem de 8px no corpo. A solução de Meouw funciona perfeitamente. Se você quiser, tenho um pequeno teste para demonstrar o problema.
CpnCrunch
3
Na verdade, acho que depende do que você realmente deseja obter. A questão é um pouco ambígua. Sua resposta está correta se você deseja apenas as cordas relativas à viewport ou ao elemento body, mas isso não ajuda no caso em que você deseja a posição absoluta do elemento (que eu imagino ser o que a maioria das pessoas deseja) . A resposta de meouw também não fornece isso, a menos que você remova os bits '-scrollLeft' e '-scrollTop'.
CpnCrunch #
4
@CpnCrunch: Entendo o que você quer dizer agora; Não sabia que você estava se referindo à parte final da minha resposta. Quando o corpo tem uma margem, sua caixa delimitadora será deslocada pelo número de pixels em cada lado respectivo. Nesse caso, você também precisará subtrair o estilo da margem calculada das coordenadas do corpo. Vale ressaltar que as redefinições de CSS removem a margem de <body>.
Andy E
3
element.getBoundingClientRect().topnão retorna o deslocamento superior correto no caso de um position: fixedelemento no iOS (iPhone 8) se ele contiver um elemento de entrada focado e o teclado virtual deslizar para cima. Por exemplo, se o deslocamento real da parte superior da janela for 200px, o relatório será 420px, onde 220px é a altura do teclado virtual. Se você definir elementos position: absolutee posicioná-los na mesma posição como se fossem fixos, obterá os 200 pixels corretos. Eu não sei uma solução para isso.
Jānis Elmeris
327
As bibliotecas se esforçam para obter compensações precisas para um elemento.
aqui está uma função simples que faz o trabalho em todas as circunstâncias que eu tentei.
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;
alterar: el = el.parentNode para: el = el.offsetParent; e parece funcionar para iframes aninhados agora ... Estou pensando que era isso que você pretendia?
297 Adam
4
Esta solução está incompleta. Tente colocar uma borda grossa em uma div e aninhe-a algumas vezes. Em qualquer versão do Firefox (2-5), ela será desabilitada pela (s) largura (s) da borda (mesmo no modo de conformidade com os padrões).
ck_
3
não existe uma maneira mais limpa de fazer isso, como as funções el.totalOffsetLeft e totalOffsetTop? O jQuery certamente tem essa opção, mas é uma pena que não exista um método oficial para isso, precisamos aguardar o DOM4? Como estou construindo um aplicativo de tela HTML5, acho que a melhor solução seria inserir um elemento de tela em um iframe para que eu possa obter coordenadas reais com clientX e clientY quando clicamos no elemento.
Baptx # 30/12
1
Então, @ Adam e meouw, você está dizendo que o primeiro bloco de código está errado? Então por que não remover isso completamente? (Esta questão tem visto bastante alguns espectadores ao longo dos anos; pode ser bom para as coisas remover, se eles estão errados?)
Arjan
2
@baptx: Eu sei que esta é uma resposta tardia, mas não vi seu comentário antes. Veja minha resposta abaixo para obter uma alternativa mais compatível com os padrões - você nem precisa realmente do código de fallback, pois os navegadores o suportam há muito tempo.
Andy E
242
Isso funcionou para mim (modificado da resposta mais votada):
function getOffset(el){const rect = el.getBoundingClientRect();return{
left: rect.left + window.scrollX,
top: rect.top + window.scrollY
};}
Apenas esta solução funciona para mim quando o elemento é colocado em divcujo centro usando CSS top:50%, left:50%; transform:translate(-50%, -50%);... excelente. Concorde com a pergunta @ScottBiggs. Lógico é buscar a simplicidade.
nelek 03/09/15
3
talvez não é um vencedor causa é o mesmo que a solução de Andy E, mas não funciona em navegadores antigos <IE9
niltoid
getBoundingClientRect provoca uma enorme repaint pico em meus gráficos de desempenho
frumbert
1
Você deve definir rectusando var, letou const. Caso contrário, é definido como window.rect.
hev1
2
left: rect.left + window.scrollX + (rect.width / 2), top: rect.top + window.scrollY + (rect.height / 2)irá retornar a posição média de um elemento
abhishake
97
Se você quiser que seja feito apenas em javascript , aqui estão alguns liners usandogetBoundingClientRect()
window.scrollY + document.querySelector('#elementId').getBoundingClientRect().top // Y
window.scrollX + document.querySelector('#elementId').getBoundingClientRect().left // X
A primeira linha retornará, offsetTopdigamos Y, em relação ao documento. A segunda linha retornará, offsetLeftdigamos, X em relação ao documento.
getBoundingClientRect() é uma função javascript que retorna a posição do elemento em relação à janela de visualização da janela.
Essa deve ser a solução. Não há código bs longo aqui, é compreensível e muito preciso!
E Alexis MT
2
e se o elemento estiver dentro de um elemento rolável? A única maneira de fazer isso é para resumir offsetTop de todos os elementos pai, como outras respostas sugerem
Dmitri Pisarev
Como Dmitri afirma, isso é incorreto e muito defeituoso. Não deve ter tantos votos positivos quanto ele. SEMPRE estará também em um elemento rolável porque o próprio documento pode ser rolado. Em outras palavras, a menos que o documento inteiro caiba na janela de visualização, ele sempre estará incorreto se o usuário rolou a janela principal.
Lev
46
Os elementos HTML na maioria dos navegadores terão: -
offsetLeft
offsetTop
Eles especificam a posição do elemento em relação ao pai mais próximo que possui layout. Esse pai geralmente pode ser acessado pela propriedade offsetParent.
IE e FF3 têm
clientLeft
clientTop
Essas propriedades são menos comuns, elas especificam uma posição de elementos com a área do cliente pai (a área acolchoada faz parte da área do cliente, mas a borda e a margem não).
Se a página incluir, pelo menos, qualquer "DIV", a função fornecida por meouw lançará o valor "Y" além dos limites da página atual. Para encontrar a posição exata, você precisa lidar com os offsetParent e parentNode.
Experimente o código fornecido abaixo (está marcado para FF2):
como nas outras soluções, mesmo com o FF 24.4, o código acima não funciona quando as larguras das bordas existem como parte do layout de posicionamento.
rob
Você é um salva-vidas. Estou trabalhando com alguns erros profundamente profundos do GWT agora e jogar isso em um método JSNI resolve todos os meus problemas!
Will Byrne
35
Você pode adicionar duas propriedades para Element.prototypeobter a parte superior / esquerda de qualquer elemento.
modificar Element.prototypeé geralmente considerado uma má ideia . Isso leva a um código muito difícil de manter. Além disso, esse código não conta para rolagem.
Jared Forsyth
23
Para recuperar a posição relativa à página com eficiência e sem usar uma função recursiva: (inclui o IE também)
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;
Incluir o importante scrollTop / scrollLeft torna essa resposta um pouco mais correta.
scunliffe
19
Que tal algo assim, passando o ID do elemento e ele retornará à esquerda ou no topo, também podemos combiná-los:
1) encontre à esquerda
function findLeft(element){var rec = document.getElementById(element).getBoundingClientRect();return rec.left + window.scrollX;}//call it like findLeft('#header');
2) encontre o topo
function findTop(element){var rec = document.getElementById(element).getBoundingClientRect();return rec.top + window.scrollY;}//call it like findTop('#header');
ou 3) encontre a esquerda e a parte superior juntas
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');
Você pode ser melhor atendido usando uma estrutura JavaScript, que possui funções para retornar essas informações (e muito mais!) De maneira independente do navegador. Aqui estão alguns:
@ Costa Todos eles usam esse tipo de função, embora esse seja um campo em evolução, pois navegadores diferentes se adaptam de maneira diferente à especificação. Grande parte do código lida com "consertar" coisas que dão errado. Você realmente deve olhar o código fonte.
Shalom Craimer
18
@ scraimer: jQuery e YUI NÃO são estruturas !!! Estas são bibliotecas ! Não é o mesmo. Citando jquery.com : "O jQuery é uma biblioteca JavaScript rápida, pequena e rica em recursos ". Citando yuilibrary.com (você também pode ver a palavra "mágica" no URL ...): "YUI é uma biblioteca JavaScript e CSS de código aberto gratuita para criar aplicativos da Web altamente interativos".
Sk8erPeter
29
Então você deve usar bibliotecas enormes apenas para esta tarefa simples? Não é necessário. Eu odeio que toda vez que quero fazer algo com js, recebo essas soluções jQuery. jQuery não é JS!
Opptatt Jobber
1
@OpptattJobber Concordo ... JQuery não é javascript. Ele se baseia em Javascript, mas é uma linguagem de programação completamente diferente.
Nick Manning
5
@NickManning Não é um idioma novo, é uma camada de abstração para o DOM que elimina a necessidade de escrever soluções de compatibilidade e desempenho diretamente no seu código. Se você não usa o jQuery, deve estar usando algum tipo de camada de abstração.
Ginman
15
jQuery .offset () obterá as coordenadas atuais do primeiro elemento ou definirá as coordenadas de cada elemento, no conjunto de elementos correspondentes, em relação ao documento.
Por alguma razão, não está dando os mesmos resultados no IE em comparação com outros navegadores. Eu acho que no IE está dando posição relativa para a janela, por isso, se você rolar, você vai ter resultados diferentes no IE em relação aos outros
Abdul Rahim Haddad
1
offset () é confundido pelo zoom, pelo menos no Android Chrome, por isso é inútil. stackoverflow.com/a/11396681/1691517 mostra uma maneira tolerante ao zoom.
Timo Kähkönen
10
Peguei a resposta de @ meouw, adicionei o clientLeft que permite a borda e criei três versões:
getAbsoluteOffsetFromBody - semelhante ao @ meouw, obtém a posição absoluta em relação ao corpo ou ao elemento html do documento (dependendo do modo quirks)
getAbsoluteOffsetFromGivenElement - retorna a posição absoluta em relação ao elemento especificado (relatedEl). Observe que o elemento fornecido deve conter o elemento el, ou ele se comportará da mesma maneira que getAbsoluteOffsetFromBody. Isso é útil se você tiver dois elementos contidos em outro elemento (conhecido) (opcionalmente vários nós na árvore de nós) e desejar torná-los na mesma posição.
getAbsoluteOffsetFromRelative - retorna a posição absoluta relativa ao primeiro elemento pai com a posição: relativa. Isso é semelhante ao getAbsoluteOffsetFromGivenElement, pelo mesmo motivo, mas irá apenas até o primeiro elemento correspondente.
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 };}
Se você ainda está tendo problemas, principalmente em relação à rolagem, tente acessar http://www.greywyvern.com/?post=331 - Observei pelo menos um pedaço de código questionável no getStyle, o que deve ser bom se os navegadores se comportarem , mas não testou o resto.
Interessante ... mas no Edge, getAbsoluteOffsetFromBody (elemento) .top retorna um valor diferente enquanto eu navego, no Chrome ele permanece consistente enquanto eu navego. Parece que o Edge está se ajustando à posição de rolagem. Quando o elemento é deslocado para fora da vista, recebo um valor negativo.
Norman
getAbsoluteOffsetFromRelative fez o meu dia, tive que reproduzir a dica da ferramenta de autoinicialização sem o Javascript da autoinicialização, isso me ajudou muito.
Nolyurn 13/08/19
Caso o Meouw mude seu nome de usuário, vincule-o para responder: stackoverflow.com/a/442474/3654837 . (Eu não quero esbarrar neste tópico antigo, então sim, eu coloquei um comentário)
Mukyuu
8
se estiver usando jQuery, o plugin de dimensões é excelente e permite que você especifique exatamente o que deseja.
por exemplo
Posição relativa, posição absoluta, posição absoluta sem preenchimento, com preenchimento ...
Continua, digamos que há muito que você pode fazer com isso.
Além disso, o bônus de usar o jQuery é o tamanho de arquivo leve e o uso fácil; você não voltará para o JavaScript sem ele posteriormente.
Este é o melhor código que eu consegui criar (funciona também em iframes, ao contrário do offset do jQuery ()). Parece que o webkit tem um comportamento um pouco diferente.
Com base no comentário 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 };}
Infelizmente, isso não funciona para todos os elementos encontrados em um documento HTML moderno. Incorporados <svg>elementos, por exemplo, não têm offsetLeft, offsetTope offsetParentpropriedades.
Jonathan Eunice
É justo DIVou IMGnão SVG. Exibir "Veja um exemplo de coordenadas"? você pode encontrar o objeto svg na posição call getOffsetRect , tentar e depender do trabalho do objeto.
21416 KingRider
7
A abordagem mais limpa que encontrei é uma versão simplificada da técnica usada pelo jQuery offset. Semelhante a algumas das outras respostas com que começa getBoundingClientRect; Em seguida, usa o windowe documentElementpara ajustar a posição de rolagem, bem como coisas como a margem na body(muitas vezes o padrão).
Embora seja provável que isso se perca na base de tantas respostas, as principais soluções aqui não estavam funcionando para mim.
Até onde eu sabia, nenhuma das outras respostas teria ajudado.
Situação :
em uma página HTML5, eu tinha um menu que era um elemento nav dentro de um cabeçalho (não o cabeçalho THE, mas um cabeçalho em outro elemento).
Eu queria que a navegação ficasse no topo assim que um usuário rolasse para ela, mas antes disso o cabeçalho estava em posição absoluta (para que eu pudesse sobrepor algo mais).
As soluções acima nunca acionaram uma mudança porque .offsetTop não mudaria, pois era um elemento posicionado absoluto. Além disso, a propriedade .scrollTop era simplesmente a parte superior do elemento mais ... ... ou seja, 0 e sempre seria 0.
Quaisquer testes que eu executei utilizando esses dois (e o mesmo com os resultados getBoundingClientRect) não me diriam se a parte superior da barra de navegação rolou para a parte superior da página visível (novamente, conforme relatado no console, eles simplesmente permaneceram os mesmos números ao rolar ocorreu).
Solução
A solução para mim estava utilizando
window.visualViewport.pageTop
O valor da propriedade pageTop reflete a seção visível da tela, permitindo-me rastrear onde um elemento está em referência aos limites da área visível.
Provavelmente desnecessário dizer que, sempre que estou lidando com rolagem, espero usar esta solução para responder programaticamente ao movimento dos elementos que estão sendo rolados.
Espero que isso ajude mais alguém.
NOTA IMPORTANTE: Parece funcionar atualmente no Chrome e no Opera e definitivamente não no Firefox (6-2018) ... até o Firefox suportar o visualViewport, eu recomendo NÃO usar esse método (e espero que eles façam isso em breve ... faz muito mais sentido do que o resto).
ATUALIZAÇÃO:
Apenas uma observação sobre esta solução. Embora eu ainda ache o que descobri ser muito valioso para situações em que "... responda programaticamente ao movimento de elementos sendo rolados". é aplicável. A melhor solução para o problema que tive foi usar CSS para definir posição: pegajosano elemento Usando o sticky, você pode fazer com que um elemento fique no topo sem usar javascript (OBSERVAÇÃO: há momentos em que isso não funcionará tão efetivamente quanto alterar o elemento para fixo, mas para a maioria dos usos, a abordagem do sticky provavelmente será superior)
UPDATE01:
Então percebi que para uma página diferente, eu tinha um requisito em que precisava detectar a posição de um elemento em uma configuração de rolagem levemente complexa (paralaxe mais elementos que rolam como parte de uma mensagem). Percebi naquele cenário que o seguinte fornecia o valor que utilizava para determinar quando fazer algo:
isso é muito provável que seja no topo de tantas respostas quando você clica ativo para classificar as respostas
Lucchi
@ lucchi: D, bem, eu suponho que eu poderia remover o texto @ the top ... embora eu tenha acontecido com este novamente e percebi que havia encontrado uma solução melhor para o meu próprio problema ... embora minha resposta seja mais nota de rodapé para as respostas mais completas. Eu suspeito que meus requisitos talvez não fossem tão comuns que as outras respostas não funcionaram para mim?
MER
1
De qualquer forma, agradeço a sua resposta, foi apenas para lhe dizer que, qualquer pessoa que se interessar estará ciente de que você escreveu algo novo. Você não está sozinho ...
lucchi
5
Eu fiz isso assim, para ter compatibilidade cruzada com navegadores antigos.
// 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;}
Usei com sucesso a solução de Andy E para posicionar um modal de bootstrap 2, dependendo do link em uma linha da tabela em que um usuário clica. A página é uma página Tapeçaria 5 e o javascript abaixo é importado na classe de página java.
Esse código js me ajudou, eu tenho um aplicativo antigo de formulários da web usando vários espaços reservados para injetar páginas .aspx e não consegui descobrir como anexarChild () de uma caixa pop-up que eu estava criando para colocá-lo na janela de exibição porque toda a árvore do DOM está danificada com vários espaços reservados e marcação incorreta. Usar o body.getBoundingClientRect () e usar o topo no posicionamento era o que eu precisava. Obrigado.
Brad Martin
1
Depois de muita pesquisa e teste, isso 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 };}
Como navegadores diferentes estão processando bordas, preenchimentos, margens e etc. de maneira diferente. Eu escrevi uma pequena função para recuperar as posições superior e esquerda de um elemento específico em cada elemento raiz que você deseja na dimensão precisa:
Obter posição de div em relação à esquerda e na parte superior
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
I para baixo votado porque parte inferior e direita não são propriedades de deslocamento ()
Macroman
@ MacroMan, eu respeito sua decisão, mas já expliquei no texto que "o código inferior e direito não foi testado". Além disso, vou atualizar meu código muito em breve.
Vishal
Eu acho que é el.offsetTope el.offsetLeft(o OP não diz nada sobre jQuery ... Eu não sei por que sua resposta usa jQuery ou ...)
Respostas:
A abordagem correta é usar
element.getBoundingClientRect()
:O Internet Explorer oferece suporte a isso desde que você provavelmente se preocupe e, finalmente, foi padronizado nas Visualizações CSSOM . Todos os outros navegadores o adotaram há muito tempo .
Alguns navegadores também retornam propriedades de altura e largura, embora isso não seja padrão. Se você está preocupado com a compatibilidade do navegador mais antigo, verifique as revisões desta resposta para obter uma implementação degradada otimizada.
Os valores retornados por
element.getBoundingClientRect()
são relativos à viewport. Se você precisar dele em relação a outro elemento, basta subtrair um retângulo do outro:fonte
<body>
.element.getBoundingClientRect().top
não retorna o deslocamento superior correto no caso de umposition: fixed
elemento no iOS (iPhone 8) se ele contiver um elemento de entrada focado e o teclado virtual deslizar para cima. Por exemplo, se o deslocamento real da parte superior da janela for 200px, o relatório será 420px, onde 220px é a altura do teclado virtual. Se você definir elementosposition: absolute
e posicioná-los na mesma posição como se fossem fixos, obterá os 200 pixels corretos. Eu não sei uma solução para isso.As bibliotecas se esforçam para obter compensações precisas para um elemento.
aqui está uma função simples que faz o trabalho em todas as circunstâncias que eu tentei.
fonte
Isso funcionou para mim (modificado da resposta mais votada):
Usando isso, podemos chamar
ou
fonte
div
cujo centro usando CSStop:50%, left:50%; transform:translate(-50%, -50%);
... excelente. Concorde com a pergunta @ScottBiggs. Lógico é buscar a simplicidade.rect
usandovar
,let
ouconst
. Caso contrário, é definido comowindow.rect
.left: rect.left + window.scrollX + (rect.width / 2), top: rect.top + window.scrollY + (rect.height / 2)
irá retornar a posição média de um elementoSe você quiser que seja feito apenas em javascript , aqui estão alguns liners usando
getBoundingClientRect()
A primeira linha retornará,
offsetTop
digamos Y, em relação ao documento. A segunda linha retornará,offsetLeft
digamos, X em relação ao documento.getBoundingClientRect()
é uma função javascript que retorna a posição do elemento em relação à janela de visualização da janela.fonte
Os elementos HTML na maioria dos navegadores terão: -
Eles especificam a posição do elemento em relação ao pai mais próximo que possui layout. Esse pai geralmente pode ser acessado pela propriedade offsetParent.
IE e FF3 têm
Essas propriedades são menos comuns, elas especificam uma posição de elementos com a área do cliente pai (a área acolchoada faz parte da área do cliente, mas a borda e a margem não).
fonte
Se a página incluir, pelo menos, qualquer "DIV", a função fornecida por meouw lançará o valor "Y" além dos limites da página atual. Para encontrar a posição exata, você precisa lidar com os offsetParent e parentNode.
Experimente o código fornecido abaixo (está marcado para FF2):
fonte
Você pode adicionar duas propriedades para
Element.prototype
obter a parte superior / esquerda de qualquer elemento.Isso é chamado assim:
Aqui está uma demonstração comparando os resultados com o jQuery
offset().top
e.left
: http://jsfiddle.net/ThinkingStiff/3G7EZ/fonte
Element.prototype
é geralmente considerado uma má ideia . Isso leva a um código muito difícil de manter. Além disso, esse código não conta para rolagem.Para recuperar a posição relativa à página com eficiência e sem usar uma função recursiva: (inclui o IE também)
fonte
Que tal algo assim, passando o ID do elemento e ele retornará à esquerda ou no topo, também podemos combiná-los:
1) encontre à esquerda
2) encontre o topo
ou 3) encontre a esquerda e a parte superior juntas
fonte
Você pode ser melhor atendido usando uma estrutura JavaScript, que possui funções para retornar essas informações (e muito mais!) De maneira independente do navegador. Aqui estão alguns:
Com essas estruturas, você pode fazer algo como:
$('id-of-img').top
obter a coordenada de pixel y da imagem.fonte
jQuery .offset () obterá as coordenadas atuais do primeiro elemento ou definirá as coordenadas de cada elemento, no conjunto de elementos correspondentes, em relação ao documento.
fonte
Peguei a resposta de @ meouw, adicionei o clientLeft que permite a borda e criei três versões:
getAbsoluteOffsetFromBody - semelhante ao @ meouw, obtém a posição absoluta em relação ao corpo ou ao elemento html do documento (dependendo do modo quirks)
getAbsoluteOffsetFromGivenElement - retorna a posição absoluta em relação ao elemento especificado (relatedEl). Observe que o elemento fornecido deve conter o elemento el, ou ele se comportará da mesma maneira que getAbsoluteOffsetFromBody. Isso é útil se você tiver dois elementos contidos em outro elemento (conhecido) (opcionalmente vários nós na árvore de nós) e desejar torná-los na mesma posição.
getAbsoluteOffsetFromRelative - retorna a posição absoluta relativa ao primeiro elemento pai com a posição: relativa. Isso é semelhante ao getAbsoluteOffsetFromGivenElement, pelo mesmo motivo, mas irá apenas até o primeiro elemento correspondente.
Se você ainda está tendo problemas, principalmente em relação à rolagem, tente acessar http://www.greywyvern.com/?post=331 - Observei pelo menos um pedaço de código questionável no getStyle, o que deve ser bom se os navegadores se comportarem , mas não testou o resto.
fonte
se estiver usando jQuery, o plugin de dimensões é excelente e permite que você especifique exatamente o que deseja.
por exemplo
Posição relativa, posição absoluta, posição absoluta sem preenchimento, com preenchimento ...
Continua, digamos que há muito que você pode fazer com isso.
Além disso, o bônus de usar o jQuery é o tamanho de arquivo leve e o uso fácil; você não voltará para o JavaScript sem ele posteriormente.
fonte
Este é o melhor código que eu consegui criar (funciona também em iframes, ao contrário do offset do jQuery ()). Parece que o webkit tem um comportamento um pouco diferente.
Com base no comentário de meouw:
fonte
jQuery
usar$.browser.webkit
; Você precisará brincarnavigator.userAgent
para fazer o mesmo com o puroJavaScript
.Se você estiver usando jQuery, esta poderia ser uma solução simples:
fonte
Diferença entre pequeno e pequeno
Veja um exemplo de coordenadas: http://javascript.info/tutorial/coordinates
fonte
<svg>
elementos, por exemplo, não têmoffsetLeft
,offsetTop
eoffsetParent
propriedades.DIV
ouIMG
nãoSVG
. Exibir "Veja um exemplo de coordenadas"? você pode encontrar o objeto svg na posição call getOffsetRect , tentar e depender do trabalho do objeto.A abordagem mais limpa que encontrei é uma versão simplificada da técnica usada pelo jQuery
offset
. Semelhante a algumas das outras respostas com que começagetBoundingClientRect
; Em seguida, usa owindow
edocumentElement
para ajustar a posição de rolagem, bem como coisas como a margem nabody
(muitas vezes o padrão).Mostrar snippet de código
fonte
Embora seja provável que isso se perca na base de tantas respostas, as principais soluções aqui não estavam funcionando para mim.
Até onde eu sabia, nenhuma das outras respostas teria ajudado.
Situação :
em uma página HTML5, eu tinha um menu que era um elemento nav dentro de um cabeçalho (não o cabeçalho THE, mas um cabeçalho em outro elemento).
Eu queria que a navegação ficasse no topo assim que um usuário rolasse para ela, mas antes disso o cabeçalho estava em posição absoluta (para que eu pudesse sobrepor algo mais).
As soluções acima nunca acionaram uma mudança porque .offsetTop não mudaria, pois era um elemento posicionado absoluto. Além disso, a propriedade .scrollTop era simplesmente a parte superior do elemento mais ... ... ou seja, 0 e sempre seria 0.
Quaisquer testes que eu executei utilizando esses dois (e o mesmo com os resultados getBoundingClientRect) não me diriam se a parte superior da barra de navegação rolou para a parte superior da página visível (novamente, conforme relatado no console, eles simplesmente permaneceram os mesmos números ao rolar ocorreu).
Solução
A solução para mim estava utilizando
O valor da propriedade pageTop reflete a seção visível da tela, permitindo-me rastrear onde um elemento está em referência aos limites da área visível.
Provavelmente desnecessário dizer que, sempre que estou lidando com rolagem, espero usar esta solução para responder programaticamente ao movimento dos elementos que estão sendo rolados.
Espero que isso ajude mais alguém.
NOTA IMPORTANTE: Parece funcionar atualmente no Chrome e no Opera e definitivamente não no Firefox (6-2018) ... até o Firefox suportar o visualViewport, eu recomendo NÃO usar esse método (e espero que eles façam isso em breve ... faz muito mais sentido do que o resto).
ATUALIZAÇÃO:
Apenas uma observação sobre esta solução.
Embora eu ainda ache o que descobri ser muito valioso para situações em que "... responda programaticamente ao movimento de elementos sendo rolados". é aplicável. A melhor solução para o problema que tive foi usar CSS para definir posição: pegajosano elemento Usando o sticky, você pode fazer com que um elemento fique no topo sem usar javascript (OBSERVAÇÃO: há momentos em que isso não funcionará tão efetivamente quanto alterar o elemento para fixo, mas para a maioria dos usos, a abordagem do sticky provavelmente será superior)
UPDATE01:
Então percebi que para uma página diferente, eu tinha um requisito em que precisava detectar a posição de um elemento em uma configuração de rolagem levemente complexa (paralaxe mais elementos que rolam como parte de uma mensagem). Percebi naquele cenário que o seguinte fornecia o valor que utilizava para determinar quando fazer algo:
Espero que esta resposta seja mais amplamente útil agora.
fonte
Eu fiz isso assim, para ter compatibilidade cruzada com navegadores antigos.
Mais sobre coordenadas em JavaScript aqui: http://javascript.info/tutorial/coordinates
fonte
Para obter o deslocamento total de um elemento, você pode resumir recursivamente todas as compensações pai:
com esta função de utilitário, o deslocamento superior total de um elemento dom é:
fonte
Agradeço à ThinkingStiff pela resposta , esta é apenas outra versão.
fonte
Usei com sucesso a solução de Andy E para posicionar um modal de bootstrap 2, dependendo do link em uma linha da tabela em que um usuário clica. A página é uma página Tapeçaria 5 e o javascript abaixo é importado na classe de página java.
javascript:
}
Meu código modal:
O link no loop:
E o código java na classe da página:
Espero que isso ajude alguém, este post ajudou.
fonte
Depois de muita pesquisa e teste, isso parece funcionar
consulte http://jsbin.com/xuvovalifo/edit?html,js,output
fonte
Só pensei em jogar isso lá fora também.
Não pude testá-lo em navegadores mais antigos, mas funciona nos mais recentes dos principais 3. :)
fonte
Como navegadores diferentes estão processando bordas, preenchimentos, margens e etc. de maneira diferente. Eu escrevi uma pequena função para recuperar as posições superior e esquerda de um elemento específico em cada elemento raiz que você deseja na dimensão precisa:
Para recuperar a posição esquerda, você deve retornar:
fonte
fonte
el.offsetTop
eel.offsetLeft
(o OP não diz nada sobre jQuery ... Eu não sei por que sua resposta usa jQuery ou ...)