Inifinite Scroll logic issue - javascript

The problem that I am facing is exactly the same as in this question - Need small logic for infinite scroll jquery
The only problem is I cannot use the accepted solution. The solution is perfect but does not work in my case.
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
/*Ajax logic*/
}
});
This logic asks the user to scroll to the end of the page for the condition to be satisfied and then makes the call. This used to work before but now I had to increase my footer by adding some content which is much larger than the window height. The user no longer scrolls down to the very end for this logic to work.
The solution adds an offset but the problem is that when the user scrolls up and down a little(with the solution of the above mentioned question) he makes multiple ajax calls which are not desired.
I am racking my brains but I would like to hear from you guys to!
Thanks

I found an answer myself and jotting it down for anyone else with a similar problem.
Logically, I capped the ceiling for $(window).scrollTop() so that it doesn't increase once it reaches the footer. Subtracted the footer offset and added one more condition with the difference of 1 px. The code is like this:
$(window).scroll(function() {
var scrollpos = $(window).scrollTop();
var docHgt = $(document).height();
var wndwHgt = $(window).height();
var footerH = $("#footer").height();
/* Capping to a Ceiling */
if(scrollpos > (docHgt - wndwHgt-footerH))
scrollpos = (docHgt - wndwHgt-footerH);
if (( scrollpos >= (docHgt - wndwHgt-footerH))&& (scrollpos <(docHgt - wndwHgt - footerH + 1))) {
/*Ajax logic*/
}
});
Not the best way but a tradeoff!

Related

Transform on Scroll - as smooth as on medium.com

i'm pretty sure a few of you guys know the website medium.com articles page.
For example, here: Click
There is a very "easy" effect on this page when you scroll down – opacity and transform changes. Not a big deal at first sight. I've implemented the same effect probably more then 10 times on websites already.
But if you take a closer look at it, you can see how absolutely perfect smooth this is. Seems like the text is perfectly gliding above the surface. (Im checking it on the latest Chrome)
I was keen if this is just imagination, and quickly built up the same thing to check this. So i came up with this code:
var windowTop;
var limit = 420;
function parallax(){
parallaxElem.css({
"opacity": (1 - (windowTop / limit)),
"-webkit-transform":"translate3d(0," + (100 * (windowTop / limit)) + "px,0)",
"-ms-transform":"translate3d(0," + (100 * (windowTop / limit)) + "px,0)",
"transform":"translate3d(0," + (100 * (windowTop / limit)) + "px,0)"
});
}
$(window).on('scroll', function(){
windowTop = $(window).scrollTop();
parallax();
});
And it's by far not as smooth as the code on the Medium website.
Anyone any idea, what they are doing to get this super smooth scroll transform effect? I just can't find it out – their code is too complex/too compressed for me, to get any information out of it.
Thank's a lot for any answer in advance!
Regards
Mark
The biggest improvement is to go from this:
$(window).on('scroll', function(){
windowTop = $(window).scrollTop();
parallax();
});
to:
$(window).on('scroll', function(){
window.requestAnimationFrame(parallax);
});
Store windowTop inside of the parallax function. There's no point in making that an out of scope variable.
Additionally, although you don't have it in your sample code "parallaxElem" should be an out of scope variable, because you don't want to do a DOM search for the element on every scroll.

Issue with "rubber-band" scrolling in Chrome

On my webpage, I have an element $('.detailViewHandle') that adjusts its position based on the window's scroll position. I'm running into issues because of elastic scrolling (which I've also seen referred to as 'rubber-band' scrolling); if the user scrolls very quickly beyond the limits of the page, the positioning of the element gets thrown off. I tried to account for when the user scrolls past the limits of the page by checking the following conditions:
$(window).scrollTop() > 0
$(window).scrollTop() + $(window).height() < $(document).height()
Here's the complete code:
$(window).scroll(function(){
var offset = 332;
var scrollTop = $(window).scrollTop();
var scrollBottom = $(window).scrollTop() + $(window).height();
if(scrollTop > 0 && scrollBottom < $(document).height()){
$('.detailViewHandle').css('top', $(window).height()-$(window).scrollTop()-$('.projectOverviewPhoto').height()+$('.detailViewHandle').height()/2-offset);
}
});
Is there a way to completely disable elastic scrolling in Chrome on OSX? I don't seem to have this issue in Firefox.
I also can't set overflow:hidden for the body and html (which I've seen in other responses) because I require that the overflow is visible for part of the page.
It ended up being quite a simple fix. It turns out that there's some lag with the scrolling, so the scrollTop might jump from 150 to 0. That left my div in the wrong position on the page. By just setting the conditional to respond to when the scrollTop is >= 0, I was able to fix the issue.
if(scrollTop >= 0 && scrollBottom <= $(document).height()){

Infinite scroll with no content

Maybe this is just me thinking of a way to create a really obnoxious "Site under construction" page, but is there anyway to create an infinite scroll when you don't actually have any content? So essentially, you would just scroll down a white page forever?
Would it work to simply use two page and constantly "refetch" the other page each time you approach the bottom of the one you're currently on? This might be a terrible idea from the memory standpoint of the browser, but I thought with only two pages that may not be an issue.
I don't know why you will need such thing but you can increase the height while scrolling by the amount you scrolled or such thing
var windowHeight = $(window).height();
var oldScrollTop = 0 ;
$(document).ready(function(){
$('body').height(windowHeight+50);
})
$(window).scroll(function(){
var scrollTop = $(this).scrollTop();
var newHeight = windowHeight + scrollTop;
if(scrollTop > oldScrollTop)
{
oldScrollTop = scrollTop;
$('body').height(newHeight);
}
});
Check this fiddle out http://jsfiddle.net/Lx563/

Get scrollable height of a page

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

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

Categories