jQuery's scrollTop() behaving strange on Android browsers including Chrome - javascript

I'm having trouble with an animated scrollbar. The intended behaviour should be on clicking the nav-button, scroll with ease to the end of the page(and a little break near the end).
Now the problem on PC works perfect. On android device (I tried my phone), the scrollTop value and the ($(document.body).height() - $(window).height()) do not match. There is exactly 55px less with the scrollTop thus acting all sorts of strange... Also sometimes it works sometimes it doesn't. I've figured it has something to do with the browser bar collapsing and upsetting the value...but i can't figure it out.
I've tried the following: initializing the variables on scroll event, i've tried vanilla js that didn't work. Need help :) for reference http://www.developer.morningmood.org , also i've printed out the values on bottom of the page if it helps. Here's the code.
contactF = Math.floor($(document.body).height() - $(window).height());
$("#cont").click(function(){
if ($(document).scrollTop() < contactF && flagScroll==true){ //flag stops other buttons from beying pushed
flagScroll = false;
var inter = setInterval(function(){
var doc = $(document).scrollTop();
if (doc == contactF){ // this is the final desired position
clearInterval(inter);
flagScroll = true;
pix = 10; //pixels to jump
return;
}
if (doc >= contactF-50){ // this is a break on aproach
pix = 1;
}
$(document).scrollTop(doc + pix);
}, 10);
}
})
EDIT: also to find the bug, you nedd to scroll from the top of the page all the way to the bottom, if from the top of the page you just push the contact button it works. but if you scroll it doesn't, it upsets the value...

Had the same exact problem and spent a whole day to figure it out.
You are right about the address bar collapse on Android chrome messing it up. Turns out the jQuery function $(window).height() always reports the viewport height that is before the address bar collapses. To get the correct value, use window.innerHeight instead. You can find more information about URL bar resizing here https://developers.google.com/web/updates/2016/12/url-bar-resizing
You can also find people asking similar questions regarding the safari address bar auto-hide, the solutions are similar. Mobile Safari $(window).height() URL bar discrepancy

Related

Problem with scrolldown in slow manner using javascript

I needed JavaScript for automatic scroll down in a smooth/slow manner.
I have a form with many radio buttons which is quite similar to survey form.
I used script from the below mentioned link. This link works fine smoothly for scrolling downwards.
But problem comes when you reach the bottom of page and cannot scroll upwards.
I am not so good in JavaScript. Does anyone here has solution or fix to this?
Link to Stack Overflow thread:
Slow down onclick window.scrollBy
function scrollByRate(y, rate)
{
//calculate the scroll height
var scrolling = Math.max( document.getElementsByTagName('html')[0].scrollTop, document.body.scrollTop);
//save the old value as "static" var
arguments.callee.tmp = arguments.callee.tmp || scrolling + y;
//make a little scrolling step
window.scrollBy(0, (arguments.callee.tmp - scrolling) / rate);
//are we arrived? if no, keep going recursively, else reset the static var
if(arguments.callee.tmp - scrolling > 100) setTimeout(function() { scrollByRate(y, rate); }, 10);
else arguments.callee.tmp = undefined;
}
Scrolling down slowly
I can see your approach having a negative impact on performance. It looks like the browser will block until the target scroll destination has been reached.
My suggestion is to use what is out there for smooth scrolling already. The scrollTo method of any scrollable pane (e.g. window object but also a scrollable div for example) has a "behavior" property that you can set to "smooth", e.g.:
window.scrollTo({
top: 100,
left: 100,
behavior: 'smooth'
});
Keep in mind that the compatibility at the time of writing is limited to Chrome, Firefox, Edge and Opera which means you'll have problems on Internet Explorer and Safari (so all Apple products). I myself use a polyfill to get the smooth scrolling back on my application, this one in particular: https://github.com/iamdustan/smoothscroll

How to create a website with 'infinite' scrolling space?

I have an idea for a website but I am not yet sure on how to achieve the desired result. The end product would be a website where a series of visible connected nodes are generated based on data that comes back from a database.
The first concern is that I will need the website to accommodate any generated content which could span in any direction.
So does anyone know how to achieve an 'infinite' scrolling website? I have seen this kind of thing for online idea boards where the user can move their mouse in any direction and the page begins to scroll, with the page expanding seemingly infinitely.
You can try something like this:
// Fetch variables
var scrollTop = $(document).scrollTop();
var windowHeight = $(window).height();
var bodyHeight = $(document).height() - windowHeight;
var scrollPercentage = (scrollTop / bodyHeight);
// if the scroll is more than 90% from the top, load more content.
if(scrollPercentage > 0.9) {
// Load content
}
The first thing that strikes my mind on the concept of infinite scrolling is Facebook! The page at qnimate might be the code you are looking for -
qnimate.com/facebook-style-infinite-scroll
For infinity scrolling in either direction you will have to tweak the code to include window.pageXOffset
Other links that I would recommend checking out is -
sitepoint.com/jquery-infinite-scrolling-demos/
tutsplus.com/articles/vertical-and-horizontal-scrolling-with-fullpagejs

Vertical scroll on mobile - hammer.js element in page

There are a million similar questions but I can't find an answer that works for me.
Here is the situation:
I have an HTML page, and within that page is an element that I am using hammer.js on.
Need to be able to scroll like this:
--->
While also being able to pinch-to-zoom (and subsequently pan on that zoomed element) on the seating chart element above.
The element itself works perfectly. I'm using doubletap, pinch, pinchend, pan, and panend on it.
Now, in the event that the element is totally zoomed out (I'm keeping track of the scale for this reason), I would like the entire page to scroll when using it on a mobile browser (aka the finger will be dragging the page up).
I have tried almost everything under the sun at this point. I can't seem to get it to manually scroll to a specific position (I have tried setting window.scrollTop and using window.scrollTo() with no results).
If someone could point me in the right direction, I'll worship you and your family for the next...say....13 days. Heck, maybe even 14.
TL;DR
- Have we pinch zoomed on the element? If so, handle panning around that element with glee!
- Are we fully zoomed out / pinched out on the element? If so, mobile users should be able to scroll the page like normal!
Thanks
Chris
You may try window.scrollTo to "simulate" normal scroll. Like so:
var currentScroll = 0;
var currentScale = 1; //"fully zoomed out" state
hammer.on("panstart", function (ev) {
currentScroll = window.scrollY;
});
hammer.on("pan", function(ev) {
if (currentScale == 1) {
//abort pan and scroll window instead
window.scrollTo(0, currentScroll + ev.deltaY * -1);
return;
}
//do stuff with pan here...
});

Inline JavaScript seems to load randomly, if at all

First off, I'd like to say that I'm sorry if this is an easy question. I'm fairly new to the HTML/CSS scene, and haven't even arrived at the Javascript one yet.
Here's my problem. I have a website I'm trying to build for my uncle, which you can see here. (it's still deep in pre-alpha stage, so the links don't work). It works fine as a local file, but as soon as I host it, my 'sticky' header starts to stick too soon, if at all. Reloading the page works about 1 time in 10.
I may or may not have isolated the cause of the problem: my placeholder. My sticky code itself works fine most of the time, except for one thing: as the sticky bar docks, it becomes fixed and the text jumps up 90-odd pixels. To combat this, I added lines 6 and 7 to my code below:
var sticky = document.querySelector('.sticky');
var origOffsetY = sticky.offsetTop;
function onScroll(e) {
window.scrollY >= origOffsetY ? sticky.classList.add('fixed') :
sticky.classList.remove('fixed');
window.scrollY >= origOffsetY ? jQuery('.content').css("paddingTop", "88.8125px"):
jQuery('.content').css("paddingTop", "0px");
}
document.addEventListener('scroll', onScroll);
It basically sticks a placeholder in there to stop that jump. It works fine, except now it's broken my code. I have experimented a bit and discovered that the placeholder seems to load randomly, and the header just goes weird. That's the best I can do.
It seems to be the placeholder code breaking it, as without the code it seems to work fine, perhaps after a couple of reloads. However, I am completely stumped. Has anyone got any idea how to fix it?
(Tested in Chrome 64 bit and 32 bit, as well as Chrome for Android, although that's glitchy on another level. Works fine as a local page, but not when hosted.)
It seems that the these code is executed too early that the image is not loaded yet, you can use chrome dev tool to add a pause to break to var origOffsetY = sticky.offsetTop;.
Then you can see 2 cases: 22 or 642
You can further inspect that the image, which should be the banner, is not completed when 22 condition is met, and if you use document.querySelector('.splash img') to get it and check its height, you'll see 0. While in the 642 case, you'll get 500.
The difference may be sometimes the image come from cache, sometimes it load from internet, so it may or may not able to decide the height when your script is executed.
So we have to make sure the image which is in the .splash is already loaded:
<script>
// Wrap the logic to a function for call.
var stickFunction = function() {
var sticky = document.querySelector('.sticky');
var origOffsetY = sticky.offsetTop;
function onScroll(e) {
window.scrollY >= origOffsetY ? sticky.classList.add('fixed') :
sticky.classList.remove('fixed');
window.scrollY >= origOffsetY ? jQuery('.content').css("paddingTop", "88.8125px"):
jQuery('.content').css("paddingTop", "0px");
}
document.addEventListener('scroll', onScroll);
}
// Get the image element
var splashImage = document.querySelector('.splash img');
// Check if image is complete or not.
if (splashImage.complete) { // If completed, do the logic.
stickFunction();
} else { // If not, tell the image to call the function for you when it is loaded.
splashImage.onload = stickFunction;
}
</script>

jquery .scrollTop() screen height

I have been writing a small script that shortens documents that are being output on a JSON feed of mine.
I realised that with longer messages, on minimising it could skip a few and you'd have to scroll back to find where you were and so added a scroll function to take you back to the top of the message on minifying. This turned out to be quite annoying when it fired every single time - so I thought, why not make it fire only when the top of the element is above the screen?
And this is where I am stuck --> $(window).scrollTop(); simply doesn't want to output the screen height for me, it's infuriating. I tried with different browsers and the only one .scrollTop() worked for correctly was Internet Explorer.
Here is the function below:
function jexpand(id){
var elm=$('#d'+jdesc[id].i); // element
var ofs=elm.offset().top; // element height - works fine
var top=$(window).scrollTop(); // Y U NO WORK?!!!
if(jdesc[id].e==true){ // boolean to check whether to expand or contract
jdesc[id].e=false; // change boolean flag
if(ofs < top) $('html').animate({scrollTop:($('#'+jdesc[id].i).offset().top)-(20)+'px'},'slow'); // animate to top minus 20 pixels
elm.html(jdesc[id].d.substring(0,347)+'...<br><div class="readmore"><span id="'+id+'">Show More</span></div>');
}else{
jdesc[id].e=true;
elm.html(jdesc[id].d+'<br><div class="readmore"><span id="'+id+'">Show Less</span></div>');
}
$('.readmore span').click(function(){jexpand(this.id)}); // reset click trigger
//alert(top+' <-> '+ofs);
}
When I uncomment the alert() at the bottom in a browser other than IE (I tried chrome, mozilla, chrome android, boat browser android) I get a message akin to:
[object Window] <-> 1077.5625
[object Window] is obviously not a number that can be greater or less than the element height! So what does this mean, is there another flag I need to ask of it? At first I assumed it might be the wrong element I was refering so tried top=$('body').scrollTop();, html, etc, I even tried using div wrapper elements but to no avail.
I am using jquery 1.11.0 and with 1.9.1 I had the same issue.
Am I trying to return the screen top in the wrong way or have all my browsers gone loopy?
EDIT:
Weirdly I've found an issue which may explain things a little, when I typed $(document).scrollTop() into a console it gave me the correct screen height however if I make a var top; outside of the function I get this error 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead..
I am using a webkit borrowed from html5up and this is somehow interfering with the code. Now to find out what it is....
Sorry for the confusion, without this script everything works fine grr...
Try this way
JS CODE:
$(window).scrollTop(0); // this will scroll to top of the page
LIVE DEMO:
http://jsfiddle.net/dreamweiver/fZrz7/6/
Happy Coding :)
What about $(document).scrollTop()? It always worked for me.
Try smth like this..
if($(window).scrollTop()>500){
elm.html(jdesc[id].d.substring(0,347)+'...<br><div class="readmore"><span id="'+id+'">Show More</span></div>');}
else{
elm.html(jdesc[id].d+'<br><div class="readmore"><span id="'+id+'">Show Less</span></div>');
}
If work try next with
var ofs=elm.offset().top;
Try this:
$(document).height(); //returns window height
$(document).scrollTop(); //returns scroll position from top of document
$(selector)[0].scrollHeight;
$(document).prop('scrollHeight');

Categories