134

How do I determine the distance between the very top of a div to the top of the current screen? I just want the pixel distance to the top of the current screen, not the top of the document. I've tried a few things like .offset() and .offsetHeight, but I just can't wrap my brain around it. Thanks!

rlemon
  • 16,698
  • 11
  • 85
  • 121
Joel Eckroth
  • 2,174
  • 3
  • 17
  • 21
  • 2
    you might want to [check this out](http://www.quirksmode.org/js/findpos.html) – Joseph Mar 26 '12 at 21:59
  • 8
    `el.getBoundingClientRect().top+window.scrollY` – caub Jan 29 '16 at 19:43
  • 3
    @caub Eh, it's just `el.getBoundingClientRect().top`. Adding the scroll position adds up to the distance to the top of the document. https://developer.mozilla.org/de/docs/Web/API/Element/getBoundingClientRect – lynx Nov 30 '16 at 21:17
  • yea right, just wanted to unjquerify – caub Nov 30 '16 at 22:09

5 Answers5

249

You can use .offset() to get the offset compared to the document element and then use the scrollTop property of the window element to find how far down the page the user has scrolled:

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

The distance variable now holds the distance from the top of the #my-element element and the top-fold.

Here is a demo: http://jsfiddle.net/Rxs2m/

Note that negative values mean that the element is above the top-fold.

Jasper
  • 74,169
  • 13
  • 144
  • 142
  • How can I check if the distance is a specific number? I want to make an element sticky if it is 120px away from the top – Thessa Verbruggen Oct 31 '19 at 16:57
  • 1
    @ThessaVerbruggen You can check the `distance` variable to see if it's value is `120` but I would recommend checking for a range instead of an exact number. If for instance you scroll with a mouse-wheel, you might very well skip over 120. So if you are trying to apply some CSS or something when the element is within 120px of the top-fold, then maybe use `if (distance < 120) { /* do something */}`. Here is an updated demo: http://jsfiddle.net/na5qL91o/ – Jasper Oct 31 '19 at 22:55
  • One problem if I do this: the sticky part is flashing when I scroll. I guess because it recalculates when I scroll. Any idea how to fix this? My code: $(window).on('scroll', function () { var scrollTop = $(window).scrollTop(), elementOffset = $('#secondary').offset().top, distance = (elementOffset - scrollTop); if (distance < 120) { $('#secondary').addClass('sticky'); } else { $('#secondary').removeClass('sticky'); } }); – Thessa Verbruggen Nov 04 '19 at 14:19
72

Vanilla:

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

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

   console.log(distanceToTop);
});

Open your browser console and scroll your page to see the distance.

horahore
  • 791
  • 5
  • 8
  • 19
    This only works if the user hasn't scrolled the page. Otherwise `distanceToTop` returned is relative (can even be negative if the user has scrolled past). To take this into account, use `window.pageYOffset + someDiv.getBoundingClientRect().top` – ty. Sep 01 '18 at 18:27
  • 3
    @ty The OP is looking for the distance to the top of the screen, not to the top of the document - a negative value would be valid in this case – Drenai Mar 25 '19 at 19:54
  • This is also what I needed. I'm using Vue-toasted library and it only allows showing the toasts at absolute positions on the screen. I wanted the toast to show up close to the button I was clicking in a table and ultimately needed to use getBoundingClientRect().top in a scroll event. I also did the same in a resize event. May want to consider adding that when calculating distance to top of screen like this - never know what the client will end up doing. – theDude Mar 13 '21 at 23:20
24

This can be achieved purely with JavaScript.

I see the answer I wanted to write has been answered by lynx in comments to the question.

But I'm going to write answer anyway because just like me, people sometimes forget to read the comments.

So, if you just want to get an element's distance (in Pixels) from the top of your screen window, here is what you need to do:

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

Thats it!

Hope this helps someone :)

Furqan Rahamath
  • 1,612
  • 1
  • 15
  • 23
7

I used this:

                              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

code:

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
  • 44,747
  • 17
  • 195
  • 185
  • +1 for showing that element.offsetTop exists. element.getBoundingClientRect().top is giving me strange behaviour. I was looking to get the distance from the top of the webpage until the top of the element. – alexandre1985 Sep 14 '19 at 17:31
0

I used this function to detect if the element is visible in view port

Code:

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