Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scroll event on Android Browser not firing. Need workaround

I've created a website with a parallax street scene. See here for an archived version.

It works just fine on all major desktop browsers, and Safari Mobile. It works fine in Mobile Firefox and Chrome for Android Beta also. However the default Android browser has issues with the scroll event. Let me be clear. Scrolling is not the issue. The div scrolls as required. The scroll event doesn't fire. This issue I experience on Honeycomb as well as ICS.

I'm not concerned about other mobile browsers because for mobile screen sizes one usually does not see the parallax scene; mediaqueries and conditional JavaScript loading take care of that. Responsive design and all that jazz.

Basically, I've written a parallise() jQuery plugin that positions each image based on its position and 'depth'. This function is bound to the scroll event.

On Android Browser, this event only fires at the start of the next touch, instead of continuously.

OK, so I thought that perhaps if I bound the function to touchstart, touchmove, and touchend events I would solve my issue. No cigar. Other touch events are also bugged. Applying the suggested workaround causes the events to fire, but as I have to e.preventDefault(), scrolling (the whole point of the exercise) is disabled.

What if I just poll the position of the stage div relative to the window div? Turns out that the position information is only updated at the start of the next touch.

I am at the end of my tether. Any help would be much appreciated.

like image 524
Xandor Schiefer Avatar asked Nov 13 '22 03:11

Xandor Schiefer


1 Answers

Even if the touch events worked correctly on the bugged versions of Android, and you were then effectively able to track the native scroll position during a drag, this would be prone to error. For example, it wouldn't account for the momentum animation which happens after the touching has finished.

iOS and Android make sacrifices to improve the performance of scrolling. On both platforms, it's not possible to get the accurate scroll position until the scroll has completed. The scroll event (on the <body>) doesn't fire until the momentum animation is finished. So while your original question is about scroll events on an overflowing <div>, fixing this might not be totally helpful for you anyway.

If you want an animation to update in time with the scroll, then you need to perform the scroll programatically rather than using the browser's native scroll. The best library to do this is iScroll. You can achieve parallax effects very easily as seen in this demo.

If you need more complex effects (the walking character, in your example), you can opt for the "probe" version of iScroll which allows pixel-perfect polling of scroll position in return for reduced performance.

However, there are many downsides to using iScroll:

  • You may need to change your markup and styling
  • It is unnecessary overhead for desktop browsers, but due to markup changes may be difficult to use only as a fallback
  • The scrolling will not feel perfect - on iOS, with its usually excellent scrolling performance - the slight difference in momentum calculation can feel jarring. On Android, the scrolling can become more laggy than usual.
like image 66
Nevett Avatar answered Nov 16 '22 04:11

Nevett