On desktop browsers, window.scroll fires off continuously as the browser is scrolled. However, in my testing on iOS and Android Chrome, it only fires when the scrolling has finished.
I tried touchmove but that had the same behavior - only firing when the movement finished.
Is there an event on mobile devices that fires continuously, like a desktop browser?
Apparently there's no way to get passed it because the "iOS devices freeze the DOM manipulation during the scroll event"!
Take a look at this link the scroll start section! http://demos.jquerymobile.com/1.0/docs/api/events.html
Might want to take a look at this site:
http://andyshora.com/mobile-scroll-event-problems.html
It helps explains why your going to be banging you head against a wall.
Related
I got event listener to the scroll and everything works fine with desktop browsers(when scrolling starts - the event fired straight away) and chrome browser in mobile(chrome latest version + android version 5.0), but with other mobile browsers(ff, android browser) this works differently, and after googling for some I found the reason: it's because the scroll event is not fired until the scrolling action comes to a complete stop(releasing the finger from the screen).
My question is there some workaround for this, perhaps some best practice, so it will fire normally(as for desktop) and without dramatically performance changes?
*JS solution only(no for jquery).
You can use iScroll. It does not depend on jQuery and achieves what you want ( firing scroll events on mobile platforms ~continuously ) among other things.
You can refer to this answer for how to implement this using iScroll.
I agree the answer of Mohit Bhardwaj and I just want to say some important thing about iScroll.
The iScroll runs depend on css3 translate and the js event such as touchMove, touchStart and touchEnd. You can just think it handle the whole scroll system in your page or the element container you set it to handle.
One thing you should know, if you want to listen the scroll event in iScroll, you must import the iscroll-probe.js, and set the probeType param with 2 or 3. Otherwise you would not get the scroll event.
The iScroll version 5 is good, I use it in a lot of project. You can see it docs and code
here
If I understand correctly, Chrome mobile stops JS code execution while scrolling in order to improve scrolling performance. I was wondering if it is possible to have my code keep running while scrolling?
Most mobile browsers just don't fire the onscroll event while scrolling.
There doesn't seem to be a generic solution to it either.
You can check this blog article with some test examples.
I have a website where I'd like to implement drag-and-drop in both desktop and mobile. I was able to do it in the desktop, and the mobile interface works as well, as long as the document doesn't scroll. Unfortunately, I haven't found a consistent way to prevent the document from scrolling in mobile browsers.
Here is what I have so far:
On the iPhone, I can preventDefault on either touchstart or touchmove. This lets me handle the touchmove event before calling preventDefault and canceling the document scroll.
On the Android, I must prevent touchstart!
Unfortunately, however, if I prevent touchstart, I don't get any more touchmove events! So are there any better ways to do it? Perhaps making everything position: fixed on the fly when someone does touchstart?
I would have been happy to overflow: auto, but unfortunately I think that only works in Android 4, i.e. tons of Android users won't be able to use it. Meanwhile, iScroll and other solutions seem to be kind of slow and -- worse yet -- don't really prevent the document scrolling either. Is this still the case?
In short, what to do?
It is well know that Mobile Safari pauses Javascript execution on a webpage when
you switch to different browser tab
switch to a different iOS app (e.g. when you get an incoming call the phone app)
You can subscribe to the window's "pagehide" and "pageshow" events to detect imminent suspension and reactivation of Javascript.
The problem is, those events do not fire when tab-switching (1.) on an iPad Mobile Safari. On an iPhone Mobile Safari everything is fine, just as described above.
It's trivial to demonstrate:
<!DOCTYPE html>
<html>
<head>
<script>
window.addEventListener("pagehide", function(evt){
var logger = document.getElementById('log_id');
logger.innerText = logger.innerText + " pagehide fired!";
}, false);
</script>
</head>
<body>
<div id="log_id"></div>
</body>
</html>
It fires on iPads (iOS5 and iOS6 Preview3) only when doing app-switching (2.) and not on tab-switching (1.). All iPhones work fine..
Has anyone been able to detect an imminent tab-switching on the iPad browser?
The reactivation of Javascript when the tab becomes active again can be detected by a heart beat loop as described in this discussion of the same topic.
Try to check focus and blur on document.
Why you need Page Visibility API?
You can use storage event to say other pages, who is active.
You can use timers (setInterval) to check time from last timer fire. And if its more bigger than expected - page was hidden, because most browsers stop timer then page is hidden.
I agree with Pinal: Use focus/blur! But i suggest not on document, but rather on window.
Just register a listener to them and do your stuff in there.
As http://caniuse.com/#feat=pagevisibility states, the feature you want to use is not well implemented. (Edit: Just tested it in a mini test-case - it works on iOS 5/6 - even though caniuse.com asserts different)
If you try to use a timer, you could try requestAnimationFrame as an alternative to setInterval.
Fixed by Apple in iOS7.
(Just tried in the iPad Simulator)
Following from Sebastian's answer, these days (comparing 2013 to 2021) page visibility works reasonably well: see https://www.w3.org/TR/page-visibility/#example-1-visibility-aware-video-playback for more around subscribing to 'visibilitychange' for hidden/visible states.
This seems to be more useful than focus/blur these days as it covers visible-but-not-selected windows if concerned also about multi-window operating systems.
A few questions here:
Is there anyway to keep iOS from freezing javascript on the page while scrolling?
Does iOS freeze javascript when your in another tab or if you switch apps?
Are there any other major javascript limitations on iOS?
iOS 6.x suspends all event timers in response to touch events like scrolling and has a tendency not to start up all the timers again once the event is done. It's a well known iOS 6 bug that is super-annoying. It pretty much breaks parallax and stuff. Some people have resorted to building their own scroll functionality.
Here's another StackOverflow on the same topic:
iOS 6 safari, setInterval doesn't get fired
and another:
setInterval pauses in iphone/ipad (mobile Safari) during scrolling
and here is the closest thing you'll get to a bug report on it (Apple doesn't make bug reports public to maintain the illusion of perfection, so developers made their own bug site): http://openradar.appspot.com/12756410
This bit of code will unfreeze timers that are broken / lost / destroyed by iOS during a page scroll: https://gist.github.com/ronkorving/3755461
This is another attempt to fix the freeze: iOS 6 js events function not called if has setTimeout in it
Unfortunately, there is nothing you can do to fire events WHILE page scrolling. Like fade out a back-to-top link when scrolling up the page. When it comes to scrolling, iOS6 is incapable of rubbing it's tummy and patting it's head. (iOS5 works fine, btw. This is a regression)
To answer the third question, a decent-sized limitation is that sometimes innerHTML just plain doesn't work. From the accepted answer:
It happens when the CPU of the phone is very busy (say 100%). Then the rendering engine sometimes forget about innerHTML settings.
The solution included in my unify project is to test if there is an element in childNodes, otherwise apply it again.