How can I monitor scroll position while scrolling in Safari on iOS?
Asked Answered
S

6

26

I currently use $(window).bind('scroll', foo); to monitor $(window).scrollTop() and do stuff to create a parallax effect.

In all desktop browsers foo() is called for each pixel the user scrolls, and everything is nice and dandy. In Safari on iOS, the scroll event is only fired AFTER the scrolling is finished.

I added $(window).bind('touchmove', foo); to make sure the function is called during the swipe in iOS, and it got me a little bit further. When user releases finger, the page continues to scroll, but the event stops firing.

Any ideas?

Serrulation answered 10/2, 2012 at 9:28 Comment(0)
D
4

When I saw your question, I was planning to do a polyfill for this (if such does not exist?). Unfortunately I've had very little time.

The idea is to have a setInterval, which is initiated ontouchstart, and it checks whether document.body.scrollTop has changed since last time, eg. for every 20 milliseconds. And if it is, then we manually dispatch the scroll event. Otherwise we clearInterval since apparently there's no more scrolling happening.

This it would be in brief. If you got more time (than I do), then feel free to try with those guidelines.

Edit: Now, reading further, the same idea is seems to be suggested on the other answer. Are you certain that intervals are stopped whilst scrolling on iPad?

Dispatch answered 13/2, 2012 at 8:18 Comment(4)
I tried the same at hakoniemi.net/labs/onscroll.html and ended up with same resolution: iOS elastic scroll can't be tracked. There's no event listener for it + both timeout / interval doesn't execute during scroll. And because there's no requestAnimationFrame in iOS5, this seems impossible to solve.Dispatch
Surely you don't expect rAF to run if the interval fails to run. It is, however, FWIW, possible to get an up-to-date reading in the web socket-powered Safari Dev Tools while momentum scroll is in progress.Agnostic
Hey, we can handle touchmove instead of this mess setInterval, which can be bad for berformaceMier
Indeed, intervals don't seem to be executed while scrolling.Overload
A
4

I highly recommend using the "Skrollr" javascript library. It is by far the best mobile scrolling animation option that I've found to date and is very easy to get up and running quickly. Create animations and manipulate CSS based on a start and end scroll position. Create as many data scroll positions and animations as you need for most standard CSS properties.

In the following example the background color would animate over the course of a 500 pixel scroll:

<div data-0="background-color:rgb(0,0,255);" data-500="background-color:rgb(255,0,0);">WOOOT</div>

Checkout the repository on Git: https://github.com/Prinzhorn/skrollr

Skrollr Demo Example: http://prinzhorn.github.io/skrollr/

Awesome real world example: http://www.fontwalk.de/03/

Avigation answered 24/4, 2014 at 13:32 Comment(1)
Thanks for the reference. I am dealing with the same issue and hope skrollr will help, but going through the awesome documentation I am already confident with that.Brittneybrittni
E
2

Apple's webpage for iPhone 5c uses some parallax scrolling effects that seem to continue with your finger still touching the screen and scrolling. So I guess javascript can't be entirely disabled during scroll. Tumult Hype provides this functionality too.

Erythrite answered 21/3, 2014 at 10:10 Comment(0)
H
1

While this isn't possible out of the box, so to speak, you can do it using iscroll

So, you'd use iScroll for iOS and Android mobile devices / tablets, and use the way you're currently doing it for desktop devices.

iScroll has a bunch of options for callback functions to be called on certain events - such as 'onScrollMove', 'onBeforeScrollEnd', 'onTouchEnd', etc. Unfortunately, there's not an option to execute a callback on "EVERY position change, including changes cause by the momentum of scrolling after the user has stoped touching the screen". But, it's easy enough to add one.

In the iScroll source, around line 127, near the "//Events" comment, add a new variable:

onPosChange: null

Then, around line 308, at the end of the "_pos" function, add this line:

if (this.options.onPosChange) this.options.onPosChange.call();

(that will just call the function passed in the "onPosChange" option, if it exists).

Having done that, the following example code will set up iScroll for the div with id="iscroll_container", and will print the Y-offset to the console each time it changes:

var myScroll;
function loaded() {
    myScroll = new iScroll('iscroll_container', { onPosChange: actOnScroll });
}

document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);

//Use this for high compatibility (iDevice + Android)
document.addEventListener('DOMContentLoaded', function () { setTimeout(loaded, 200); }, false);

function actOnScroll(){
    console.log('got a scroll move! Vert offset is: ' + myScroll.y);
}

Note, Ben the Bodyguard Parallax Site works on iPad by using iScroll (they use a much older version of iscroll and don't do it exactly the way I described here)

Also, Life of Pi Parallax Site works on iPad really nicely - I can't figure out how they do it, but at least it proves it's possible!

Hallucinosis answered 7/5, 2013 at 14:17 Comment(0)
C
0

This could be a bug with jQuery itself: http://bugs.jquery.com/ticket/6446

That ticket has been open for a while and pertains to iOS 4, but perhaps you should investigate calculating the scroll position with pure javascript.

Carn answered 17/2, 2012 at 18:43 Comment(0)
D
0

As I know there is no javascript execution while scrolling on the most mobile devices. There are some workarounds (f.e. iscroll) out there. Iscroll is using css-technique "transform". But there is no way to execute javascript while scrolling. I suppose the smoothe scrolling-algorithm is too expensive.

Deplane answered 22/1, 2013 at 17:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.