From b645781f4da5f14130a57c10c79bd65ec51a1aca Mon Sep 17 00:00:00 2001 From: scottjehl Date: Wed, 7 Sep 2011 18:08:12 -0400 Subject: [PATCH] implemented native overflow scrolling based on support for -[prefix]-overflow-scrolling: touch. True fixed headers and footers come supported as well. --- Makefile | 1 + build.xml | 1 + docs/_assets/css/jqm-docs.css | 1 + js/index.php | 1 + js/jquery.mobile.fixHeaderFooter.js | 4 +- js/jquery.mobile.fixHeaderFooter.native.js | 59 ++++++++++++++++++++++ js/jquery.mobile.navigation.js | 46 +++++++++++------ js/jquery.mobile.support.js | 5 -- themes/default/jquery.mobile.core.css | 40 ++++++++++++++- 9 files changed, 135 insertions(+), 23 deletions(-) create mode 100644 js/jquery.mobile.fixHeaderFooter.native.js diff --git a/Makefile b/Makefile index cc664c6d..6614b2de 100644 --- a/Makefile +++ b/Makefile @@ -67,6 +67,7 @@ JSFILES = js/jquery.ui.widget.js \ js/jquery.mobile.controlGroup.js \ js/jquery.mobile.links.js \ js/jquery.mobile.fixHeaderFooter.js \ + js/jquery.mobile.fixHeaderFooter.native.js \ js/jquery.mobile.media.classes.js \ js/jquery.mobile.init.js diff --git a/build.xml b/build.xml index 62428e64..e1012b22 100644 --- a/build.xml +++ b/build.xml @@ -51,6 +51,7 @@ jquery.mobile.controlGroup.js, jquery.mobile.links.js, jquery.mobile.fixHeaderFooter.js, + jquery.mobile.fixHeaderFooter.native.js, jquery.mobile.media.classes.js, jquery.mobile.init.js"/> diff --git a/docs/_assets/css/jqm-docs.css b/docs/_assets/css/jqm-docs.css index 0044db3c..0f53fb3e 100644 --- a/docs/_assets/css/jqm-docs.css +++ b/docs/_assets/css/jqm-docs.css @@ -21,6 +21,7 @@ dt code, dd code { font-size:1.3em; line-height:150%; } pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; } #jqm-homeheader img { width: 235px; } +img { max-width: 100%; } .ui-header .jqm-home { top:0.65em; } nav { margin: 0; } diff --git a/js/index.php b/js/index.php index bdfb6da7..93f1014c 100644 --- a/js/index.php +++ b/js/index.php @@ -33,6 +33,7 @@ $elements = array( 'jquery.mobile.controlGroup.js', 'jquery.mobile.links.js', 'jquery.mobile.fixHeaderFooter.js', + 'jquery.mobile.fixHeaderFooter.native.js', 'jquery.mobile.media.classes.js', 'jquery.mobile.init.js' ); diff --git a/js/jquery.mobile.fixHeaderFooter.js b/js/jquery.mobile.fixHeaderFooter.js index e275923a..b38209ac 100644 --- a/js/jquery.mobile.fixHeaderFooter.js +++ b/js/jquery.mobile.fixHeaderFooter.js @@ -37,7 +37,7 @@ $.fn.fixHeaderFooter = function( options ) { // single controller for all showing,hiding,toggling $.mobile.fixedToolbars = (function() { - if ( !$.support.scrollTop ) { + if ( !$.support.scrollTop || $.support.touchOverflow ) { return; } @@ -361,7 +361,7 @@ $( document ).bind( "pagecreate create", function( event ) { $( event.target ).each(function() { - if ( !$.support.scrollTop ) { + if ( !$.support.scrollTop || $.support.touchOverflow ) { return this; } diff --git a/js/jquery.mobile.fixHeaderFooter.native.js b/js/jquery.mobile.fixHeaderFooter.native.js new file mode 100644 index 00000000..b7740d9d --- /dev/null +++ b/js/jquery.mobile.fixHeaderFooter.native.js @@ -0,0 +1,59 @@ +/* +* jQuery Mobile Framework : "fixHeaderFooter" native plugin - Behavior for "fixed" headers,footers, and scrolling inner content +* Copyright (c) jQuery Project +* Dual licensed under the MIT or GPL Version 2 licenses. +* http://jquery.org/license +*/ + +(function( $, undefined ) { + +$.mobile.touchOverflowEnabled = true; + +$( document ).bind( "pagecreate", function( event ) { + if( $.support.touchOverflow && $.mobile.touchOverflowEnabled ){ + + var $target = $( event.target ), + scrollStartY = 0; + + if( $target.is( ":jqmData(role='page')" ) ){ + + $target.each(function() { + var $page = $( this ), + $fixies = $page.find( ":jqmData(role='header'), :jqmData(role='footer')" ).filter( ":jqmData(position='fixed')" ), + fullScreen = $page.jqmData( "fullscreen" ), + $scrollElem = $fixies.length ? $page.find( ".ui-content" ) : $page; + + $page.addClass( "ui-mobile-touch-overflow" ); + + $scrollElem.bind( "scrollstop", function(){ + if( $scrollElem.scrollTop() > 0 ){ + window.scrollTo( 0, $.mobile.defaultHomeScroll ); + } + }); + + if( $fixies.length ){ + + $page.addClass( "ui-native-fixed" ); + + if( fullScreen ){ + + $page.addClass( "ui-native-fullscreen" ); + + $fixies.addClass( "fade in" ); + + $( document ).bind( "vclick", function(){ + $fixies + .removeClass( "ui-native-bars-hidden" ) + .toggleClass( "in out" ) + .animationComplete(function(){ + $(this).not( ".in" ).addClass( "ui-native-bars-hidden" ); + }); + } ); + } + } + }); + } + } +}); + +})( jQuery ); diff --git a/js/jquery.mobile.navigation.js b/js/jquery.mobile.navigation.js index 332e36ad..2b9e029a 100755 --- a/js/jquery.mobile.navigation.js +++ b/js/jquery.mobile.navigation.js @@ -409,10 +409,17 @@ lastScrollEnabled = false; - var active = $.mobile.urlHistory.getActive(); + var active = $.mobile.urlHistory.getActive(), + activePage = $( ".ui-page-active" ), + scrollElem = $( window ), + touchOverflow = $.support.touchOverflow && $.mobile.touchOverflowEnabled; + + if( touchOverflow ){ + scrollElem = activePage.is( ".ui-native-fixed" ) ? activePage.find( ".ui-content" ) : activePage; + } if( active ){ - var lastScroll = $.support.touchOverflow ? $( ".ui-page-active" ).scrollTop() : $( window ).scrollTop(); + var lastScroll = scrollElem.scrollTop(); // Set active page's lastScroll prop. // If the Y location we're scrolling to is less than minScrollBack, let it go. @@ -429,11 +436,13 @@ // Make the iOS clock quick-scroll work again if we're using native overflow scrolling /* if( $.support.touchOverflow ){ - $( window ).bind( "scrollstop", function(){ - if( $( this ).scrollTop() === 0 ){ - $.mobile.activePage.scrollTop( 0 ); - } - }); + if( $.mobile.touchOverflowEnabled ){ + $( window ).bind( "scrollstop", function(){ + if( $( this ).scrollTop() === 0 ){ + $.mobile.activePage.scrollTop( 0 ); + } + }); + } } */ @@ -442,9 +451,10 @@ //get current scroll distance var active = $.mobile.urlHistory.getActive(), - toScroll = active.lastScroll || ( $.support.touchOverflow ? 0 : $.mobile.defaultHomeScroll ), + touchOverflow = $.support.touchOverflow && $.mobile.touchOverflowEnabled, + toScroll = active.lastScroll || ( touchOverflow ? 0 : $.mobile.defaultHomeScroll ), screenHeight = getScreenHeight(); - + // Scroll to top, hide addr bar window.scrollTo( 0, $.mobile.defaultHomeScroll ); @@ -453,7 +463,7 @@ fromPage.data( "page" )._trigger( "beforehide", null, { nextPage: toPage } ); } - if( !$.support.touchOverflow ){ + if( !touchOverflow){ toPage.height( screenHeight + toScroll ); } @@ -462,13 +472,19 @@ //clear page loader $.mobile.hidePageLoadingMsg(); - if( $.support.touchOverflow && toScroll ){ + if( touchOverflow && toScroll ){ + toPage.addClass( "ui-mobile-pre-transition" ); // Send focus to page as it is now display: block reFocus( toPage ); //set page's scrollTop to remembered distance - toPage.scrollTop( toScroll ); + if( toPage.is( ".ui-native-fixed" ) ){ + toPage.find( ".ui-content" ).scrollTop( toScroll ); + } + else{ + toPage.scrollTop( toScroll ); + } } //find the transition handler for the specified transition. If there @@ -479,20 +495,20 @@ promise.done(function() { //reset toPage height back - if( !$.support.touchOverflow ){ + if( !touchOverflow ){ toPage.height( "" ); // Send focus to the newly shown page reFocus( toPage ); } // Jump to top or prev scroll, sometimes on iOS the page has not rendered yet. - if( !$.support.touchOverflow ){ + if( !touchOverflow ){ $.mobile.silentScroll( toScroll ); } //trigger show/hide events if( fromPage ) { - if( !$.support.touchOverflow ){ + if( !touchOverflow ){ fromPage.height( "" ); } diff --git a/js/jquery.mobile.support.js b/js/jquery.mobile.support.js index ac095809..7b78dbcc 100644 --- a/js/jquery.mobile.support.js +++ b/js/jquery.mobile.support.js @@ -118,9 +118,4 @@ if ( !$.support.boxShadow ) { $( "html" ).addClass( "ui-mobile-nosupport-boxshadow" ); } -// For opting into touch overflow scrolling -if( $.support.touchOverflow ){ - $( "html" ).addClass( "ui-mobile-touch-overflow" ); -} - })( jQuery ); \ No newline at end of file diff --git a/themes/default/jquery.mobile.core.css b/themes/default/jquery.mobile.core.css index 9793b396..7c9d9289 100644 --- a/themes/default/jquery.mobile.core.css +++ b/themes/default/jquery.mobile.core.css @@ -23,7 +23,8 @@ .landscape .ui-page { min-height: 300px; } /* native overflow scrolling */ -.ui-mobile.ui-mobile-touch-overflow .ui-page { +.ui-page.ui-mobile-touch-overflow, +.ui-mobile-touch-overflow.ui-native-fixed .ui-content { overflow: auto; height: 100%; -webkit-overflow-scrolling: touch; @@ -62,6 +63,43 @@ .ui-content { border-width: 0; overflow: visible; overflow-x: hidden; padding: 15px; } .ui-page-fullscreen .ui-content { padding:0; } +/* native fixed headers and footers */ +.ui-mobile-touch-overflow.ui-page.ui-native-fixed, +.ui-mobile-touch-overflow.ui-page.ui-native-fullscreen { + overflow: visible; +} +.ui-mobile-touch-overflow.ui-native-fixed .ui-header, +.ui-mobile-touch-overflow.ui-native-fixed .ui-footer { + position: fixed; + left: 0; + right: 0; + top: 0; + z-index: 200; +} +.ui-mobile-touch-overflow.ui-page.ui-native-fixed .ui-footer { + top: auto; + bottom: 0; +} +.ui-mobile-touch-overflow.ui-native-fixed .ui-content { + padding-top: 2.5em; + padding-bottom: 3em; + top: 0; + bottom: 0; + height: auto; + position: absolute; +} +.ui-mobile-touch-overflow.ui-native-fullscreen .ui-content { + padding-top: 0; + padding-bottom: 0; +} +.ui-mobile-touch-overflow.ui-native-fullscreen .ui-header, +.ui-mobile-touch-overflow.ui-native-fullscreen .ui-footer { + opacity: .9; +} +.ui-native-bars-hidden { + display: none; +} + /* icons sizing */ .ui-icon { width: 18px; height: 18px; }