Determine a distância do topo de uma div ao topo da janela com javascript

127

Como determino a distância entre o topo de uma div e o topo da tela atual? Eu só quero a distância do pixel na parte superior da tela atual, não na parte superior do documento. Eu tentei algumas coisas como .offset()e .offsetHeight, mas simplesmente não consigo envolver meu cérebro em torno disso. Obrigado!

Joel Eckroth
fonte
2
você pode querer verificar isso
Joseph
7
el.getBoundingClientRect().top+window.scrollY
caub
3
@caub Eh, é só el.getBoundingClientRect().top. A adição da posição de rolagem aumenta a distância até a parte superior do documento. developer.mozilla.org/de/docs/Web/API/Element/…
lynx
sim certo, só queria desqualificar
caub

Respostas:

239

Você pode usar .offset()para obter o deslocamento comparado ao documentelemento e, em seguida, usar a scrollToppropriedade do windowelemento para descobrir o quão abaixo a página o usuário rolou:

var scrollTop     = $(window).scrollTop(),
    elementOffset = $('#my-element').offset().top,
    distance      = (elementOffset - scrollTop);

A distancevariável agora mantém a distância entre a parte superior do #my-elementelemento e a dobra superior.

Aqui está uma demonstração: http://jsfiddle.net/Rxs2m/

Observe que valores negativos significam que o elemento está acima da dobra superior.

Jaspe
fonte
Como posso verificar se a distância é um número específico? Eu quero fazer um elemento pegajoso se é 120px longe do topo
Thessa Verbruggen
@ThessaVerbruggen Você pode verificar a distancevariável para ver se é valor, 120mas eu recomendaria verificar um intervalo em vez de um número exato. Se, por exemplo, você rolar com a roda do mouse, poderá muito bem pular mais de 120. Portanto, se você estiver tentando aplicar CSS ou algo quando o elemento estiver a 120px da dobra superior, talvez use if (distance < 120) { /* do something */}. Aqui está uma demonstração atualizada: jsfiddle.net/na5qL91o
Jasper
Um problema se eu fizer isso: a parte adesiva estará piscando quando eu rolar. Eu acho que porque recalcula quando eu rolar. Alguma idéia de como consertar isso? Meu código: $ (window) .on ('scroll', function () {var scrollTop = $ (window) .scrollTop (), elementOffset = $ ('# secundário'). Offset (). Offset (). Top, distance = (elementOffset - scrollTop); if (distância <120) {$ ('# secundário'). addClass ('pegajoso');} else {$ ('# secundário'). removeClass ('pegajoso');}});
Thessa Verbruggen 4/11/19
60

Baunilha:

window.addEventListener('scroll', function(ev) {

   var someDiv = document.getElementById('someDiv');
   var distanceToTop = someDiv.getBoundingClientRect().top;

   console.log(distanceToTop);
});

Abra o console do navegador e role a página para ver a distância.

horahore
fonte
14
Isso funciona apenas se o usuário não rolou a página. Caso contrário, o distanceToTopretorno é relativo (pode até ser negativo se o usuário tiver passado a rolagem). Para levar isso em conta, usewindow.pageYOffset + someDiv.getBoundingClientRect().top
ty.
2
@ty O OP está procurando a distância para o topo da tela, não para a parte superior do documento - um valor negativo seria válida neste caso
Drenai
16

Isso pode ser alcançado puramente com JavaScript .

Vejo que a resposta que eu queria escrever foi respondida pelo lince nos comentários à pergunta.

Mas vou escrever a resposta de qualquer maneira, porque assim como eu, às vezes as pessoas esquecem de ler os comentários.

Portanto, se você deseja apenas obter a distância de um elemento (em pixels) da parte superior da janela da tela, eis o que você precisa fazer:

// Fetch the element
var el = document.getElementById("someElement");  

use getBoundingClientRect ()

// Use the 'top' property of 'getBoundingClientRect()' to get the distance from top
var distanceFromTop = el.getBoundingClientRect().top; 

É isso aí!

Espero que isso ajude alguém :)

Furqan Rahamath
fonte
1
getBoundingClient () não funciona. Em vez disso .getBoundingClientRect ()
Elnoor 22-22
@ Elnoor Obrigado pela sugestão :) Fiz as alterações necessárias.
Furqan Rahamath
Apenas incrível trabalho @MohammedFurqanRahamathM. Muito obrigado pela sua resposta :) Funciona como um encanto !! :)
Merianos Nikos
1
@MerianosNikos Obrigado. Estou feliz por ter sido de ajuda :)
Furqan Rahamath
1
mas isso só funcionaria se você não tiver recarregado no meio da página, certo?
Sagive SEO 14/07/19
7

Eu usei isso:

                              myElement = document.getElemenById("xyz");
Get_Offset_From_Start       ( myElement );  // returns positions from website's start position
Get_Offset_From_CurrentView ( myElement );  // returns positions from current scrolled view's TOP and LEFT

código:

function Get_Offset_From_Start (object, offset) { 
    offset = offset || {x : 0, y : 0};
    offset.x += object.offsetLeft;       offset.y += object.offsetTop;
    if(object.offsetParent) {
        offset = Get_Offset_From_Start (object.offsetParent, offset);
    }
    return offset;
}

function Get_Offset_From_CurrentView (myElement) {
    if (!myElement) return;
    var offset = Get_Offset_From_Start (myElement);
    var scrolled = GetScrolled (myElement.parentNode);
    var posX = offset.x - scrolled.x;   var posY = offset.y - scrolled.y;
    return {lefttt: posX , toppp: posY };
}
//helper
function GetScrolled (object, scrolled) {
    scrolled = scrolled || {x : 0, y : 0};
    scrolled.x += object.scrollLeft;    scrolled.y += object.scrollTop;
    if (object.tagName.toLowerCase () != "html" && object.parentNode) { scrolled=GetScrolled (object.parentNode, scrolled); }
    return scrolled;
}

    /*
    // live monitoring
    window.addEventListener('scroll', function (evt) {
        var Positionsss =  Get_Offset_From_CurrentView(myElement);  
        console.log(Positionsss);
    });
    */
T.Todua
fonte
+1 para mostrar que existe element.offsetTop. element.getBoundingClientRect (). top está me dando um comportamento estranho. Eu estava procurando obter a distância do topo da página da Web até o topo do elemento.
alexandre1985
0

Eu usei essa função para detectar se o elemento está visível na porta de visualização

Código:

const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);
$(window).scroll(function(){
var scrollTop     = $(window).scrollTop(),
elementOffset = $('.for-scroll').offset().top,
distance      = (elementOffset - scrollTop);
if(distance < vh){
    console.log('in view');
}
else{
    console.log('not in view');
}
});
moutasim ahmad
fonte