I am running into a weird issue when using -webkit-overflow-touch on iOS Safari.
I do have a div#viewport that has the following CSS:
#viewport{
width: 1024px;
height: 768px;
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
Inside this div I am displaying content (div.page) of twice the horizontal size. When the user has reached the end he can swipe left to get to the next page. This is my handler:
if ($('.page:visible').offset().left <= -1024){ //only change page when the page is scrolled to its end
$('.page:visible').next('.page').buildPage().end().destroyPage(); //custom functions that DO NOT CONTAIN ANY scroll manipulation
$('#viewport').scrollLeft(0);
}
The second line should be “rewinding” the newly shown page so that the user can see the left portion of the newly shown page. This works as expected on desktop, yet on iOS Safari the following happens: The new page gets shown, gets rewound and instantly bounces back to the right (I figured that out by animating the scrollLeft instead of just setting it). To make things even more strange I still get the correct values (0) when I debug, yet the displayed content does not match these.
Am I doing something wrong? Is this a bug in iOS Safari or in jQuery’s scrollLeft? Is there another way to tackle this?
EDIT: So what I just found out is that the root of the problem seems to be that the “bouncy” scroll is not finished when I trigger my swipe so it will interfer with my setting of the scrollLeft. When I wrap the $('#viewport').scrollLeft(0); in a timeout to make sure that the bounce has finished it works just as expected. Still I do not have a real clue about how to solve this. Will an event be fired when the animation ends?
EDIT #2: So what I managed to find out is that when doing the following:
$('#viewport').css('-webkit-overflow-scrolling','auto');
$('#viewport').scrollLeft(0);
$('#viewport').css('-webkit-overflow-scrolling','scroll');
I am able to “trick” the page into displaying correctly, yet this yields another really strange result: when I interact with the page the coordinates are offset so I will trigger events on the right hand side of my scrollable page. This ends when I have scrolled, coordinates will be correct then. I cannot manually trigger a scroll though.
So, what I found out is that the only way to solve this is to wrap each
.page-element in a seperate.viewport-container as each new wrapper will have an own “momentum” so you can programatically scroll the next page while the previous page is still controlled by the overflow-scrolling’s momentum.While this solves the problem described in my question, I ran into another bug that makes this approach unusable, as iOS doesn’t update its coordinates until the next scroll.
See: https://bugs.webkit.org/show_bug.cgi?id=90393 for info on that.