Get scrollable height of a page - javascript

First of all,I would like to know the difference between these terms:
- $(window).height()
- $(document).height()
- $(window).scrollTop()
These terms look somewhat similar to me and I am unable to understand the clear difference between them. Here are my answers:
$(window).height() : Gives the height of window which a user can see.
$(document).height() : Gives total height of document. This can be more/less than window height depending upon the content on the page.
$(document).scrollTop() : gives the vertical position of scrollbar in window.
Real Question:
I am trying to implement lazy loading kinda thing where I need to make a call to server when scrollbar has crossed a point 200px from bottom of page. I am unable to use the above values to get this.
Any help would be appreciated.

The window is the area that you can see - as if your screen is a window and you are looking through at the document. The document is the entire document - it could be shorter or much longer than the window.
This is the math you need:
if( $(document).height() - $(document).scrollTop() < 200 ){
//Do something
}

$(window).height(); // returns height of browser viewport
$(document).height(); // returns height of HTML document
$(window).scrollTop(); //Get the current vertical position of the scroll bar for the first element in the set of matched elements or set the vertical position of the scroll bar for every matched element.
$(window).scrollHeight(); //Height of the scroll view of an element; it includes the element padding but not its margin.

Eventually, I figured out what should be the calculations after understanding these terms. Thanks to the answers. I was almost right in my definitions.
function (isScrollable) {
var isUserAtBottom = ($(window).height() + $(window).scrollTop() + 200 > $(document).height());
if (isUserAtBottom) {
// Do something (Like Ajax call to server to fetch new elements)
return true;
}
}

Related

Hide a div until scrolled to the bottom of the page

I am making a web page (kind of like those music release pages, here is an example), and I would like certain div's at the bottom not to be shown until the user has scrolled to the bottom of the page, delay a second or two, then pop up. Kind of like a hidden feature thing.
You can also think of it like an infinite scroll, like when you drag down your Instagram feed at the top it refreshes it, and new posts show up. That's the user experience I'm looking for, only in my case it is a "finite scroll", just with some div's hidden by default.
I currently have two implementations of it, neither fully achieves the desired experience. Both used jQuery Slim.
In both implementations, #hidden is the id of my hidden-by-default div, it has style="display: none;" inline, on the div tag.
The first one looks like this:
$(window).scroll(function() {
var x = $(document).height() - $(window).height() - 20;
if( $(window).scrollTop() > x ) {
$("#hidden").delay(1000).show(0);
}
else {
$("#hidden").hide(0);
}
});
The problem with this one is that when the div shows up it changes the document height, so when you get to the bottom of the page it kind of flickers (due to recomputing the document height), and sometimes goes back to being hidden. Really bad user experience.
The second one looks like this:
$(window).scroll(function() {
if( $(window).scrollTop() > 75 ) {
$("#hidden").delay(1000).show(0);
}
else {
$("#hidden").hide(0);
}
});
This one got rid of the flickering problem by keeping the threshold static altogether, slightly better user experience, but not really flexible, in the case that my page gets longer I'll have to set a new threshold for the div to show up.
In neither of the above solutions did the delay(1000) work. The div showed up as soon as the page gets scrolled to the bottom.
Is it possible to make this design work out?
You can try this code:
$(window).on("scroll", function() {
var scrollHeight = $(document).height();
var scrollPosition = $(window).height() + $(window).scrollTop();
if ((scrollHeight - scrollPosition) / scrollHeight === 0) {
$("#hidden").delay(1000).show(0);
}
});

How do I find the browser scroll bars total scrollable height

So I know that $(window).scrollTop() will give me the current position of the browser scroll bar, but how do I find the total scrollable area?
i.e. If I scroll all the way down the final $(window).scrollTop() might equal 300px and scrolling back to the top would return it back to 0px, but suppose I wanted to find the total $(window).scrollTop() area before hand? How would I do that?
i.e. If I use $(window).scrollTop() I want something to happen when it get's to a certain point.
So pretty much is there a way to find out that $(window).scrollTop() total is 300px before hand? If the browser height is changed/resized then the $(window).scrollTop() will change, so I I'll need to find out what the new $(window).scrollTop() total is once the browser is resized.
Thanks.
You should use this to get the maximum scrolleable value:
$(document).height() - $(window).height()
You get the entire web height and substract the window height (the height that you can see on your window), so the rest of it is what is left to scroll

Load ajax when scroll reaches 80%

I am using the following code which is working when the scroll bar reaches the botttom,
if($(window).scrollTop() == $(document).height() - $(window).height()){
I however want that the ajax is fired when i reached 70% of the scroll not 100.
Provided your current check is firing when scrolled to the page's bottom, you can try some basic arithmetics:
if ($(window).scrollTop() >= ($(document).height() - $(window).height())*0.7){
//where 0.7 corresponds to 70% --^
Make sure to add a check to don't fire multiple simultaneous Ajax requests, if you didn't already.
This is rather out of the scope of the question, but if you want an example of how to prevent multiple requests from being fired simultaneously:
Declare a global var, e.g. processing.
Then incorporate it in your function:
if (processing)
return false;
if ($(window).scrollTop() >= ($(document).height() - $(window).height())*0.7){
processing = true; //sets a processing AJAX request flag
$.post("url", '<params>', function(data){ //or $.ajax, $.get, $.load etc.
//load the content to your div
processing = false; //resets the ajax flag once the callback concludes
});
}
That's a simple example of using a var to keep track if there is an active Ajax request for your scroll function or not, and it doesn't interfere with any other concurring Ajax request which you may have.
Edit: JSFiddle example
Please note that using a % to measure the document height might be a bad idea, considering that the document's height will increase each time you load something, making it trigger the Ajax request being relatively more far from the bottom of the page (absolute-size wise).
I'd recommend using a fixed value offset to prevent that (200-700 or so):
if ($(window).scrollTop() >= $(document).height() - $(window).height() - 700){
// pixels offset from screen bottom --^
Example: JSFiddle
Edit: To reproduce the issue in the first code with percentages, load 50 divs into it. When you load the next div, it'll add only 2% to the total document's height, meaning the next request will be triggered as soon as you scroll these 2% back to the 70% of the document's height. In my fixed example, the defined bottom offset will load new content only when the user is at a defined absolute pixels range from the bottom of the screen.
A quick google search for get percentage scrolled down brings up this page as the first result(with the code below, which more or less does what you want). I feel like you didn't attempt any research before asking here.
$(document).scroll(function(e){
// grab the scroll amount and the window height
var scrollAmount = $(window).scrollTop();
var documentHeight = $(document).height();
// calculate the percentage the user has scrolled down the page
var scrollPercent = (scrollAmount / documentHeight) * 100;
if(scrollPercent > 50) {
// run a function called doSomething
doSomething();
}
function doSomething() {
// do something when a user gets 50% of the way down my page
}
});

Floating elements on scroll

I was wondering how sites like Facebook, with their timeline feature, float a certain element (usually a menu bar, or sometimes a social plugin, etc) when the user has scrolled past a point such that the top of the element is off the screen, etc.
This could be seen as a more general JavaScript (jQuery?) event firing when the user has scrolled to a certain element, or scrolled down a certain number of pixels.
Obviously it would require toggling the CSS property from:
#foo { position: relative; }
to
#foo { position: fixed; }
Or with jQuery, something like:
$('#foo').css('position', 'fixed');
Another way I have seen this implemented is with blogs, where a popup will be called when you reach the bottom, or near the bottom of a page. My question is, what is firing that code, and could you link or provide some syntax/ semantics/ examples?
Edit: I'm seeing some great JS variants coming up, but as I am using jQuery, I think the plugin mentioned will do just nicely.
Take a look at this jsfiddle: http://jsfiddle.net/remibreton/RWJhM/2/
In this example, I'm using document.onscroll = function(){ //Scroll event } to detect a scroll event on the document.
I'm then calculating the percentage of the page scrolled based on it's height. (document.body.scrollTop * 100 / (document.body.clientHeight - document.documentElement.clientHeight)).
document.body.scrollTop being the number of pixels scrolled from the top, document.body.clientHeight being the height of the entire document and document.documentElement.clientHeight being the visible portion of the document, a.k.a. the viewport.
Then you can compare this value to a target percentage, an execute JavaScript. if(currentPercentage > targetPercentage)...
Here's the whole thing:
document.onscroll = function(){
var targetPercentage = 80;
var currentPercentage = (document.body.scrollTop * 100 / (document.body.clientHeight - document.documentElement.clientHeight));
console.log(currentPercentage);
if(currentPercentage > targetPercentage){
document.getElementById('pop').style.display = 'block';
// Scrolled more than 80%
} else {
document.getElementById('pop').style.display = 'none';
// Scrolled less than 80%
}
}
​If you prefer jQuery, here is the same example translated into everybody's favorite library: http://jsfiddle.net/remibreton/8NVS6/1/
$(document).on('scroll', function(){
var targetPercentage = 80;
var currentPercentage = $(document).scrollTop() * 100 / ($(document).height() - $(window).height());
if(currentPercentage > targetPercentage){
$('#pop').css({display:'block'});
//Scrolled more than 80%
} else {
$('#pop').css({display:'none'});
//Scrolled less than 80%
}
});​
An idea would be to handle the window.scroll event and determine if the user has scrolled to the bottom of the page. Here is an example:
http://chrissilich.com/blog/load-more-content-as-the-user-reaches-the-bottom-of-your-page-with-jquery/
Hope it helps!
There is a jquery plugin that might help you in the right direction.
http://imakewebthings.com/jquery-waypoints/
I just answered basically the same question here. In that case it was a table and its header, and the basic idea is like this:
function placeHeader(){
var $table = $('#table');
var $header = $('#header');
if ($table.offset().top <= $(window).scrollTop()) {
$header.offset({top: $(window).scrollTop()});
} else {
$header.offset({top: $table.offset().top});
}
}
$(window).scroll(placeHeader);
Here's a demo.
Quoting myself:
In other words, if the top of the table is above the scrollTop, then
position the header at scrollTop, otherwise put it back at the top of
the table. Depending on the contents of the rest of the site, you
might also need to check if you have scrolled all the way past the
table, since then you don't want the header to stay visible.
To answer your question directly, it is triggered by checking the scrollTop against either the position of an element, or the height of the document minus the height of the viewport (for the scrolled to bottom use case). This check is done every time the scroll event is fired (bound using $(window).scroll(...)).

Javascript to detect if item no longer visible due to scrolling

I've got a javascript slideshow at the top of my page. When a slide changes to the next image, I call another function to change the background colour of the page.
The client wants the background colour to stop changing when the slideshow is no longer in view, i.e. when the user has scrolled down the page.
Is there any way to detect if an element is no longer visible due to scrolling?
Test code in jQuery
function test() {
var $elem = $('.test');
var visibleAtTop = $elem.offset().top + $elem.height() >= $(window).scrollTop();
var visibleAtBottom = $elem.offset().top <= $(window).scrollTop() + $(window).height();
if (visibleAtTop && visibleAtBottom) {
alert('visible');
} else {
alert('invisible (at ' + (visibleAtTop ? 'bottom' : 'top') + ')');
}
}
Full working example at http://jsfiddle.net/9PaQc/1/ (Updated: http://jsfiddle.net/9PaQc/2/ )
P.S. This only checks for vertical scroll. For horizontal, just do the same with top replaced with left, Y -> X and height() -> width()
EDIT
Made it all the way jQuery (to ensure x-browser compatibility) by changing window.scrollY -> $(window).scrollTop()
You can use the jQuery $.scrollTop function, probably from a scroll event handler to script this.
Use the window.pageYOffset to determine scroll amount in window. Use current offset of the object to check if it is in view. Note that these values are mostly browser dependent, so first check if it exists then act on it.

Categories