Skip to content

Commit

Permalink
Changes to hopefully simplify and synchronize transitions and scrolling.
Browse files Browse the repository at this point in the history
- Added $.mobile.scrollTo() which synchronously scrolls the page, and is aware of any pending silentScroll() requests.

- Removed the silentScroll() call in the orientationchange and resize callback in jquery.mobile.media.js.

- Modified transition code to use $.mobile.scrollTo() so that we can synchronously scroll the window. Changed where we call the focus and scroll code to account for timing.

- Removed setTimeout() wrap around transitionPages() in the ajax callback.
  • Loading branch information
jblas committed Feb 2, 2011
1 parent b464b1b commit a0fa3d4
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 19 deletions.
23 changes: 15 additions & 8 deletions js/jquery.mobile.core.js
Expand Up @@ -134,6 +134,8 @@
$.mobile.metaViewportContent ? $( "<meta>", { name: "viewport", content: $.mobile.metaViewportContent}).prependTo( $head ) : undefined;


var silentScrollTimer = 0;

//expose some core utilities
$.extend($.mobile, {

Expand All @@ -158,20 +160,25 @@
}
},

scrollTo: function(x, y) {
if (silentScrollTimer)
clearTimeout(silentScrollTimer);
silentScrollTimer = 0;
window.scrollTo(x || 0, y || 0);
},

//scroll page vertically: scroll to 0 to hide iOS address bar, or pass a Y value
silentScroll: function( ypos ) {
ypos = ypos || 0;
// prevent scrollstart and scrollstop events
$.event.special.scrollstart.enabled = false;

setTimeout(function() {
window.scrollTo( 0, ypos );
if (silentScrollTimer)
clearTimeout(silentScrollTimer);
silentScrollTimer = setTimeout(function() {
$.mobile.scrollTo( 0, ypos );
$.event.special.scrollstart.enabled = true;
$(document).trigger( "silentscroll", { x: 0, y: ypos });
},20);

setTimeout(function() {
$.event.special.scrollstart.enabled = true;
}, 150 );
},

// find and enhance the pages in the dom and transition to the first page.
Expand Down Expand Up @@ -212,6 +219,6 @@

//window load event
//hide iOS browser chrome on load
$window.load( $.mobile.silentScroll );
$window.load( function(){$.mobile.silentScroll();} );

})( jQuery, this );
2 changes: 0 additions & 2 deletions js/jquery.mobile.media.js
Expand Up @@ -111,8 +111,6 @@ $(document).bind("mobileinit.htmlclass", function(){
} else {
$( '.ui-page' ).css( 'minHeight', ( screen.availHeight <= screen.availWidth ) ? screen.availHeight : screen.availWidth);
}

$.mobile.silentScroll();
}
//add classes to HTML element for min/max breakpoints
detectResolutionBreakpoints();
Expand Down
41 changes: 32 additions & 9 deletions js/jquery.mobile.navigation.js
Expand Up @@ -345,8 +345,6 @@

//function for transitioning between two existing pages
function transitionPages() {
$.mobile.silentScroll();

//get current scroll distance
var currScroll = $window.scrollTop(),
perspectiveTransitions = [ "flip" ],
Expand Down Expand Up @@ -381,11 +379,6 @@

removeActiveLinkClass();

//jump to top or prev scroll, sometimes on iOS the page has not rendered yet. I could only get by this with a setTimeout, but would like to avoid that.
$.mobile.silentScroll( to.data( "lastScroll" ) );

reFocus( to );

//trigger show/hide events
if( from ){
from.data( "page" )._trigger( "hide", null, { nextPage: to } );
Expand Down Expand Up @@ -423,7 +416,7 @@
pageContainerClasses = [];
};


$.mobile.scrollTo(0, 0);

if(transition && (transition !== 'none')){
$.mobile.pageLoading( true );
Expand All @@ -446,7 +439,31 @@
from.removeClass( $.mobile.activePageClass );
}
loadComplete();

// The ordering of the operations below is important for the following reasons:
//
// - The classes that are set on the viewport during a transition causes
// ui-page elements to have a height that exactly matches the viewport
// height. When removeContainerClasses() is called, these classes are removed,
// but the reflow necessary to calculate the new document height may not have
// happened yet. This means we need to delay the code that sets any previous
// scroll offset for some time so that the browser can calculate the height,
// allowing us to scroll to the proper offset.
//
// - We need to set the focus *AFTER* the classes have been removed so that we
// don't trigger the browser's auto-offset-rendering which kicks in for overflow:hidden
// elements. We also need to make sure we set it *BEFORE* we scroll so that it doesn't
// cause the browser to scroll the focused element into view after we've set our desired
// scroll position.
//
// - Finally, we set the scroll position *AFTER* the classes are unset and focus has
// been set.
removeContainerClasses();
reFocus( to );
setTimeout(function(){
reFocus( to );
$.mobile.scrollTo( 0, to.data( "lastScroll" ) );
}, 10);
});
}
else{
Expand All @@ -456,6 +473,12 @@
}
to.addClass( $.mobile.activePageClass );
loadComplete();

// The order of the code below matters. We need make sure we focus first,
// and then scroll to our desired offset since some browsers will auto scroll
// whatever gets focused programatically into view.
reFocus( to );
$.mobile.scrollTo( 0, to.data( "lastScroll" ) );
}
};

Expand Down Expand Up @@ -557,7 +580,7 @@
.appendTo( $.mobile.pageContainer );

enhancePage();
setTimeout(function() { transitionPages() }, 0);
transitionPages();
},
error: function() {
$.mobile.pageLoading( true );
Expand Down

0 comments on commit a0fa3d4

Please sign in to comment.