Issue with "rubber-band" scrolling in Chrome - javascript

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()){

Related

Inifinite Scroll logic issue

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!

Freeze element (position:fixed) for specific scroll range

I'm working on this site (http://styleguide.co/medhelp/) that has 5 sections. For one of the sections (Styles), I've got a sidenav I'm trying to get to stick in the visible frame only as long as users are scrolling in that section.
Here's what I've done thus far - I'm telling the section title & sidenav to stick after the top of the section has begun:
$(window).scroll(function(event) {
var sw = $('.fixed'),
pg = $('.styles'),
diff = pg[0].offsetTop - window.pageYOffset;
if (diff < 80 ) {
$('.fixed').css('position', 'fixed');
$('.fixed').css('top', '160px');
$('.styles').css('position', 'fixed');
$('.styles').css('top', '70px');
}
else {
$('.fixed').css('position', 'relative');
$('.fixed').css('top', '0px');
$('.styles').css('position', 'relative');
$('.styles').css('top', '0px');
}
});
I can't seem to figure out a good way to make the section title "Style" and the sidenav appear/disappear while I scroll to/from that section. Any advice? What could I do better? A simple solution demo in jsfiddle would really help!
Please click on this link & scroll down/up to know what I'm referring to: http://styleguide.co/medhelp/
I'm not going to give you a fiddle, but you need to determine when the next section would stick based on its offset from the top. At the moment what you are doing is:
// if difference top and element < 80 -> fix to top, else position is relative
First of all this means the condition will never be undone. What you need to do in order to continue is:
// once next contact section comes into screen
//(offset from the top of the screen <= screen height), give
var winHeight = $(window).height();
var calcTop = 80 - (winHeight - (winHeight - $('#nextSelector').offset().top);
$('.fixed').css('top', calcTop);
This will give the illusion of your text scrolling up as the new section comes up. I hope this helps. Also, when scrolling back up it doesn't re-stick, but you probably are aware of that.

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

Javascript: check IF page is at the top

Is there a way to check, with JavaScript, if the page is at scroll(0,0)?
Reason being I've got a full page slider that I need to pause the second the page is not at origin.
And it might not necessarily be because the page is being scrolled live as I've got internal HTML # links that would load the page right to a scrolled point without actually scrolling.
So the check needs to be is the page not at the top, as opposed to, has the page been scrolled.
Try this:
document.body.scrollTop === 0
You can check if window.scrollY (the number of pixels the window has scrolled vertically) is equal to 0. If you want to check if the window has been scrolled to its leftermost, you can check if window.scrollX (the number of pixels the window has scrolled horizontally) is equal to 0. If you combine the two, it will ensure the window is at (0,0) position.
if(window.scrollY==0){
//user scrolled to the top of the page
}
if(window.scrollX==0){
//user scrolled to the leftmost part of the page
}
if(window.scrollY==0&&window.scrollX==0){
//user scrolled to the leftmost part of the top of the page—i.e., they are at position (0, 0)
}
Demo:
var goToTop = document.querySelector('#backToTop');
goToTop.addEventListener("click", function(e){
window.scroll({top: 0, left: 0, behavior: 'smooth'});
//scroll smoothly back to the top of the page
});
window.addEventListener("scroll", function(){
if(window.scrollY==0){
//user is at the top of the page; no need to show the back to top button
goToTop.style.display = "";
} else {
goToTop.style.display = "block";
}
});
body,html{height:3000px;position:relative;margin:0}#footer{position:absolute;width:100%;bottom:0;left:0;right:0;background-color:#1e90ff;text-align:center}#backToTop{position:fixed;right:0;bottom:0;display:none;z-index:1}#header{position:absolute;width:100%;top:0;left:0;right:0;background-color:#1e90ff;text-align:center}
<div id="header">Header</div>
<button id="backToTop">Back To Top</button>
<div id="footer">Footer</div>
For better browser compatibility, use window.pageYOffset instead of window.scrollY and window.pageXOffset instead of window.scrollX.
The following code can be used in cases when full browser compatability is necessary (i.e., IE < 9):
var x = (window.pageXOffset !== undefined)
? window.pageXOffset
: (document.documentElement || document.body.parentNode || document.body).scrollLeft;
//number of pixels scrolled horizontally (work with this value instead of window.scrollX or window.pageXOffset)
var y = (window.pageYOffset !== undefined)
? window.pageYOffset
: (document.documentElement || document.body.parentNode || document.body).scrollTop;
//number of pixels scrolled vertically (work with this value instead of window.scrollY or window.pageYOffset)
Updated Answer for 2019
document.body.scrollTop is deprecated and doesn't work at all in Chrome anymore. The best way to solve this is simply looking at all three possibilities to have a cross browser solution.
!window.pageYOffset
One of these three should work on all browser types. If the value equals 0, your at the top of the viewport.
i think you can get the position using jQuery $(window).scrollTop()

Categories