A bit late, but I think I have a reliable solution without the need for setTimeout()
. After a quick look at the code, it seems that JQM 1.2.0 produces silentScroll(0)
on window.load
for a chrome-free viewport on iOS. See jquery.mobile-1.2.0.js
, line 9145:
// window load event // hide iOS browser chrome on load $window.load( $.mobile.silentScroll );
It happens that this contradicts the silentScroll()
applicative calls. Called too soon, the structure scrolls back. Called too late, the user interface flashes.
The solution is to 'silentscroll'
one-shot handler to the 'silentscroll'
event, which calls window.scrollTo()
directly ( silentScroll()
is anyway slightly larger than the asynchronous window.scrollTo()
). Thus, we remove the first released JQM silentScroll(0)
and scroll to our position immediately.
For example, here is the code that I use for deep binding to named elements (be sure to disable ajax loading in incoming links using data-ajax="false"
). Known binding names are #unread
and #unread
#p<ID>
. The title is fixed and uses the identifier #header
.
$(document).bind('pageshow',function(e) { var $anchor; console.log("location.hash="+location.hash); if (location.hash == "#unread" || location.hash.substr(0,2) == "#p") { // Use anchor name as ID for the element to scroll to. $anchor = $(location.hash); } if ($anchor) { // Get y pos of anchor element. var pos = $anchor.offset().top; // Our header is fixed so offset pos by height. pos -= $('#header').outerHeight(); // Don't use silentScroll() as it interferes with the automatic // silentScroll(0) call done by JQM on page load. Instead, register // a one-shot 'silentscroll' handler that performs a plain // window.scrollTo() afterward. $(document).bind('silentscroll',function(e,data) { $(this).unbind(e); window.scrollTo(0, pos); }); } });
There is no longer a user interface and it works reliably.
source share