mirror of
https://github.com/Hopiu/jquery-mobile.git
synced 2026-03-16 22:10:25 +00:00
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:
parent
a4b7673c12
commit
f00e3a1164
6 changed files with 282 additions and 86 deletions
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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" );
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
);
|
||||
|
||||
|
|
|
|||
271
js/jquery.mobile.fixedToolbar.js
Normal file
271
js/jquery.mobile.fixedToolbar.js
Normal 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");
|
||||
|
|
@ -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' ] );
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue