added new fixedToolbar plugin (its matching css is already in from the previous messy merge). Docs page is updated to match the new preferred syntax (no changes in API, however)

This commit is contained in:
scottjehl 2012-01-19 00:19:06 +07:00
parent a4b7673c12
commit f00e3a1164
6 changed files with 282 additions and 86 deletions

View file

@ -24,41 +24,6 @@ div.ui-mobile-viewport { overflow-x: hidden; }
.ui-mobile, .ui-mobile .ui-page { min-height: 300px; }
}
/* native overflow scrolling */
.ui-page.ui-mobile-touch-overflow,
.ui-mobile-touch-overflow.ui-native-fixed .ui-content {
overflow: auto;
height: 100%;
left: 0;
right: 0;
-webkit-overflow-scrolling: touch;
-moz-overflow-scrolling: touch;
-o-overflow-scrolling: touch;
-ms-overflow-scrolling: touch;
overflow-scrolling: touch;
}
.ui-page.ui-mobile-touch-overflow,
.ui-page.ui-mobile-touch-overflow * {
/* some level of transform keeps elements from blinking out of visibility on iOS */
-webkit-transform: rotateY(0);
}
.ui-mobile-touch-overflow.ui-native-fixed .ui-content .ui-listview {
margin-top: 0;
}
.ui-mobile-touch-overflow.ui-native-fixed .ui-content .ui-listview-inset {
margin-top: 1em;
}
.ui-mobile-touch-overflow.ui-native-fixed .ui-content .ui-listview-filter {
margin-top: .2em;
margin-bottom: 0;
}
.ui-mobile-touch-overflow.ui-native-fixed .ui-content .ui-listview-filter-inset {
margin-bottom: -.9em;
}
.ui-mobile-touch-overflow.ui-native-fixed .ui-header .ui-btn {
z-index: 10;
}
/* loading screen */
.ui-loading .ui-loader { display: block; }
.ui-loader { background-color: #000; opacity: .18; display: none; z-index: 9999999; position: fixed; width: 46px; height: 46px; top: 50%; box-shadow: 0 1px 1px -1px #fff; margin-left: -18px; margin-top: -18px; left: 50%; padding: 1px; border:0; -webkit-border-radius: 36px; -moz-border-radius: 36px; border-radius: 36px; }
@ -73,8 +38,7 @@ div.ui-mobile-viewport { overflow-x: hidden; }
.ui-bar { font-size: 16px; margin: 0; }
.ui-bar h1, .ui-bar h2, .ui-bar h3, .ui-bar h4, .ui-bar h5, .ui-bar h6 { margin: 0; padding: 0; font-size: 16px; display: inline-block; }
.ui-header, .ui-footer { display: block; }
.ui-page .ui-header, .ui-page .ui-footer { position: relative; }
.ui-header, .ui-footer { position: relative; overflow: hidden; width: 100%; border-left-width: 0; border-right-width: 0; }
.ui-header .ui-btn-left { position: absolute; left: 10px; top: .4em; }
.ui-header .ui-btn-right { position: absolute; right: 10px; top: .4em; }
.ui-header .ui-title, .ui-footer .ui-title { min-height: 1.1em; text-align: center; font-size: 16px; display: block; margin: .6em 30% .8em; padding: 0; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; outline: 0 !important; }
@ -82,51 +46,14 @@ div.ui-mobile-viewport { overflow-x: hidden; }
/*content area*/
.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; }
/* fullscreen class on ui-content div */
.ui-fullscreen { }
.ui-fullscreen img { max-width: 100%; }
/* fluid images */
.ui-mobile img {
max-width: 100%;
}
/* non-js content hiding */
.ui-nojs { position: absolute; left: -9999px; }

View file

@ -10,7 +10,7 @@
@import url( "../../structure/jquery.mobile.transitions.turn.css" );
@import url( "../../structure/jquery.mobile.transitions.flow.css" );
@import url( "../../structure/jquery.mobile.grids.css" );
@import url( "../../structure/jquery.mobile.headerfooter.css" );
@import url( "../../structure/jquery.mobile.fixedToolbar.css" );
@import url( "../../structure/jquery.mobile.navbar.css" );
@import url( "../../structure/jquery.mobile.button.css" );
@import url( "../../structure/jquery.mobile.collapsible.css" );

View file

@ -12,9 +12,9 @@
</head>
<body>
<div data-role="page" data-fullscreen="true" class="type-interior">
<div data-role="page" class="type-interior">
<div data-role="header" data-position="fixed" data-theme="f">
<div data-role="header" data-position="fixed" data-theme="f" data-fullscreen="true">
<h1>Fullscreen fixed header</h1>
<a href="../../" data-icon="home" data-iconpos="notext" data-direction="reverse" class="ui-btn-right jqm-home">Home</a>
</div>
@ -56,7 +56,7 @@
</div><!-- /content -->
<div data-role="footer" class="footer-docs" data-theme="a" data-position="fixed">
<div data-role="footer" class="footer-docs" data-theme="a" data-position="fixed" data-fullscreen="true">
<h1>Fullscreen Fixed Footer</h1>
</div>

View file

@ -45,8 +45,7 @@ $files = array(
'jquery.mobile.buttonMarkup.js',
'jquery.mobile.controlGroup.js',
'jquery.mobile.links.js',
'jquery.mobile.fixHeaderFooter.js',
'jquery.mobile.fixHeaderFooter.native.js',
'jquery.mobile.fixedToolbar.js',
'jquery.mobile.init.js'
);

View file

@ -0,0 +1,271 @@
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Behavior for "fixed" headers and footers
//>>label: Fixedtoolbar
define( [ "jquery", "jquery.mobile.widget", "jquery.mobile.core", "jquery.mobile.navigation", "jquery.mobile.page", "jquery.mobile.page.sections" ], function( $ ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, undefined ) {
$.widget( "mobile.fixedtoolbar", $.mobile.widget, {
options: {
visibleOnPageShow: true,
togglePageZoom: true,
transition: "fade", //can be none, fade, slide (slide maps to slideup or slidedown)
fullscreen: false,
tapToggle: true,
// Browser detection! Weeee, here we go...
// Unfortunately, position:fixed is costly, not to mention probably impossible, to feature-detect accurately.
// Some tests exist, but they currently return false results in critical devices and browsers, which could lead to a broken experience.
// Testing fixed positioning is also pretty obtrusive to page load, requiring injected elements and scrolling the window
// The following function serves to rule out some popular browsers with known fixed-positioning issues
// This is a plugin option like any other, so feel free to improve or overwrite it
supportBlacklist: function(){
var ua = navigator.userAgent,
platform = navigator.platform,
// Rendering engine is Webkit, and capture major version
wkmatch = ua.match( /AppleWebKit\/([0-9]+)/ ),
wkversion = !!wkmatch && wkmatch[ 1 ],
ffmatch = ua.match( /Fennec\/([0-9]+)/ ),
ffversion = !!ffmatch && ffmatch[ 1 ],
operammobilematch = ua.match( /Opera Mobile\/([0-9]+)/ ),
omversion = !!operammobilematch && operammobilematch[ 1 ],
w = window;
if(
// iOS 4.3 and older : Platform is iPhone/Pad/Touch and Webkit version is less than 534 (ios5)
( ( platform.indexOf( "iPhone" ) > -1 || platform.indexOf( "iPad" ) > -1 || platform.indexOf( "iPod" ) > -1 ) && wkversion && wkversion < 534 )
||
// Opera Mini
( w.operamini && ({}).toString.call( w.operamini ) === "[object OperaMini]" )
||
( operammobilematch && omverson < 7458 )
||
//Android lte 2.1: Platform is Android and Webkit version is less than 533 (Android 2.2)
( ua.indexOf( "Android" ) > -1 && wkversion && wkversion < 533 )
||
// Firefox Mobile before 6.0 -
( ffversion && ffversion < 6 )
||
// WebOS less than 3
( "palmGetResource" in window && wkversion && wkversion < 534 )
){
return true;
}
return false;
},
initSelector: ":jqmData(position='fixed')"
},
_create: function() {
var self = this,
o = self.options,
$el = self.element,
tbtype = $el.is( ".ui-header" ) ? "header" : "footer",
$page = $el.closest(".ui-page");
// Feature detecting support for
if( o.supportBlacklist() ){
self.destroy();
return;
}
$el.addClass( "ui-"+ tbtype +"-fixed" );
// "fullscreen" overlay positioning
// NOTE - this used to be only "data-fullscreen" on page element. Support both or deprecate page?
if( $el.jqmData( "fullscreen" ) || $page.jqmData( "fullscreen" ) ){
$el.addClass( "ui-"+ tbtype +"-fullscreen" );
$page.addClass( "ui-page-" + tbtype + "-fullscreen" );
}
// If not fullscreen, add class to page to set top or bottom padding
else{
$page.addClass( "ui-page-" + tbtype + "-fixed" );
}
self._addTransitionClass();
self._bindPageEvents();
self._bindToggleHandlers();
},
_addTransitionClass: function(){
var tclass = this.options.transition;
if( tclass && tclass !== "none" ){
// use appropriate slide for header or footer
if( tclass === "slide" ){
tclass = this.element.is( ".ui-header" ) ? "slidedown" : "slideup";
}
this.element.addClass( tclass );
}
},
_bindPageEvents: function(){
var self = this,
o = self.options,
$el = self.element;
//page event bindings
$el.closest( ".ui-page" )
.bind( "pagebeforeshow", function(){
if( o.togglePageZoom ){
self.disablePageZoom();
}
if( o.visibleOnPageShow ){
self.show();
}
} )
.bind( "pagehide", function(){
if( o.togglePageZoom ){
self.restorePageZoom();
}
});
},
_visible: false,
show: function(){
var hideClass = "ui-fixed-hidden",
$el = this.element,
scroll = $( window ).scrollTop(),
elHeight = $el.height(),
pHeight = $el.closest( ".ui-page" ).height(),
viewportHeight = Math.min( screen.height, $( window ).height() ),
tbtype = $el.is( ".ui-header" ) ? "header" : "footer";
if( this.options.transition && this.options.transition !== "none" &&
(
( tbtype === "header" && !this.options.fullscreen && scroll > elHeight ) ||
( tbtype === "footer" && !this.options.fullscreen && scroll + viewportHeight < pHeight - elHeight )
) || this.options.fullscreen ){
$el
.removeClass( "out " + hideClass )
.addClass( "in" );
}
else {
$el.removeClass( hideClass );
}
this._visible = true;
},
hide: function(){
var hideClass = "ui-fixed-hidden",
$el = this.element,
scroll = $( window ).scrollTop(),
elHeight = $el.height(),
pHeight = $el.closest( ".ui-page" ).height(),
viewportHeight = Math.min( screen.height, $( window ).height() ),
tbtype = $el.is( ".ui-header" ) ? "header" : "footer";
if( this.options.transition && this.options.transition !== "none" &&
(
( tbtype === "header" && !this.options.fullscreen && scroll > elHeight ) ||
( tbtype === "footer" && !this.options.fullscreen && scroll + viewportHeight < pHeight - elHeight )
) || this.options.fullscreen ){
$el
.removeClass( "in" )
.addClass( "out" )
.animationComplete( function(){
$el.addClass( hideClass );
});
}
else {
this.element.addClass( hideClass );
}
this._visible = false;
},
toggle: function(){
this[ this._visible ? "hide" : "show" ]();
},
_bindToggleHandlers: function(){
var self = this,
o = self.options,
$el = self.element;
// tap toggle
$el.closest( ".ui-page" )
.bind( "vclick", function( e ){
if( o.tapToggle && $el.find( e.target ).length === 0 ){
self.toggle();
}
});
},
destroy: function(){
this.element.removeClass( "ui-header-fixed ui-footer-fixed ui-header-fullscreen ui-footer-fullscreen in out fade slidedown slideup ui-fixed-hidden" )
this.element.closest( ".ui-page" ).removeClass( "ui-page-header-fixed ui-page-footer-fixed ui-page-header-fullscreen ui-page-footer-fullscreen" );
},
// for caching reference to meta viewport elem
_metaViewport: null,
// on pageshow, does a meta viewport element exist in the head?
_metaViewportPreexists: false,
// used for storing value of meta viewport content at page show, for restoration on hide
_metaViewportContent: "",
// Fixed toolbars require page zoom to be disabled, otherwise usability issues crop up
// This method is meant to disable zoom while a fixed-positioned toolbar page is visible
disablePageZoom: function(){
if( !this.options.togglePageZoom ){
return;
}
var cont = "user-scalable=no";
this._metaViewport = $( "meta[name='viewport']" );
this._metaViewportPreexists = this._metaViewport.length;
var currentContent = this._metaViewport.attr( "content" );
// If scaling's already disabled, or another plugin is handling it on this page already
if( currentContent.indexOf( cont ) > -1 ){
return;
}
else {
this._metaViewportContent = currentContent;
}
if( !this._metaViewportPreexists ){
this._metaViewport = $( "<meta>", { "name": "viewport", "content": cont } ).prependTo( "head" );
}
else{
this._metaViewport.attr( "content", this._metaViewportContent + ", " + cont );
}
},
// restore the meta viewport tag to its original state, or remove it
restorePageZoom: function(){
if( !this.options.togglePageZoom ){
return;
}
var cont = "user-scalable=no";
if( this._metaViewport.attr( "content" ).indexOf( cont ) < 0 ){
return;
}
if( this._metaViewportPreexists ){
this._metaViewport.attr( "content", this._metaViewportContent );
}
else {
this._metaViewport.remove();
}
}
});
//auto self-init widgets
$( document ).bind( "pagecreate create", function( e ){
$( $.mobile.fixedtoolbar.prototype.options.initSelector, e.target ).fixedtoolbar();
});
})( jQuery );
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");

View file

@ -39,8 +39,7 @@ define([
'order!jquery.mobile.buttonMarkup',
'order!jquery.mobile.controlGroup',
'jquery.mobile.links',
'jquery.mobile.fixHeaderFooter',
'jquery.mobile.fixHeaderFooter.native'
'jquery.mobile.fixedToolbar'
], function() {
require( [ 'jquery.mobile.init' ] );
});