mirror of
https://github.com/Hopiu/jquery-mobile.git
synced 2026-04-11 09:51:01 +00:00
more rewriting to get the toolbars working better. this change separates the toolbar markup builder portion from the controller portion, which can now be called globally to show,hide,toggle all at once. This seems to be an improvement.
This commit is contained in:
parent
2eef9f4e5d
commit
5d11ae2779
2 changed files with 145 additions and 130 deletions
|
|
@ -7,27 +7,62 @@
|
|||
(function($){
|
||||
$.fn.fixHeaderFooter = function(options){
|
||||
return $(this).each(function(){
|
||||
//make sure these things only get wrapped once
|
||||
if($(this).data('fixedapplied')){ return; }
|
||||
var el = $uipage = $(this).data('fixedapplied',true);
|
||||
var el = $uipage = $(this).data('fixedapplied',true),
|
||||
els = el.find('.ui-header,.ui-footer').wrap('<div class="ui-headfoot-placehold"><div class="ui-headfoot-wrap"></div></div>');
|
||||
//wrapper explanation: placehold wrapper sits inline and holds the height of the toolbars open while they are position abs,
|
||||
//unless it's overlay-only, in which case the height is 0 so it's hidden when pos static
|
||||
|
||||
//config options - currently driven off data attr's
|
||||
var o = $.extend({
|
||||
ignoreTargets: 'a,input,textarea,select,button,label,.ui-headfoot-placehold',
|
||||
transition: el.find('[data-headfoottransition]').attr('data-headfoottransition') || ['slidedown','slideup'],
|
||||
//also accepts a string, like 'fade'. All animations work, but fade and slidedown/up look best
|
||||
overlayOnly: el.find('.ui-fullscreen').length
|
||||
},options);
|
||||
|
||||
var els = el.find('.ui-header,.ui-footer').wrap('<div class="ui-headfoot-placehold"><div class="ui-headfoot-wrap"></div></div>'),
|
||||
tIsArray = $.isArray(o.transition),
|
||||
currentstate = 'inline';
|
||||
|
||||
//add transition types
|
||||
els.filter('.ui-header').addClass(tIsArray ? o.transition[0] : o.transition);
|
||||
els.filter('.ui-footer').addClass(tIsArray ? o.transition[1] : o.transition);
|
||||
els.filter('.ui-header').addClass( $.isArray(o.transition) ? o.transition[0] : o.transition);
|
||||
els.filter('.ui-footer').addClass( $.isArray(o.transition) ? o.transition[1] : o.transition);
|
||||
|
||||
//set placeholder heights, then bind custom events
|
||||
els
|
||||
.each(function(){
|
||||
var placehold = $(this).parents('.ui-headfoot-placehold:eq(0)');
|
||||
if(o.overlayOnly){
|
||||
placehold.height(0).addClass('ui-headfoot-overlayonly');
|
||||
}
|
||||
else{
|
||||
placehold.height($(this).parent().height());
|
||||
}
|
||||
})
|
||||
.bind('setTop',function(){
|
||||
var fromTop = $.scrollY(),
|
||||
screenHeight = window.innerHeight,
|
||||
thisHeight = $(this).parent().height();
|
||||
return $(this).parent().css('top', ($(this).is('.ui-header')) ? fromTop : fromTop + screenHeight - thisHeight);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
//single controller for all showing,hiding,toggling
|
||||
$.fixedToolbars = (function(){
|
||||
|
||||
var currentstate = 'inline',
|
||||
showAfterScroll = false,
|
||||
delayTimer,
|
||||
ignoreTargets = 'a,input,textarea,select,button,label,.ui-headfoot-placehold';
|
||||
|
||||
function allToolbars(){
|
||||
return $('.ui-header,.ui-footer');
|
||||
}
|
||||
|
||||
//for determining whether a placeholder is visible on the screen or not
|
||||
function placeHolderOutofView(thisel){
|
||||
//always return true if it's overlayOnly
|
||||
if(o.overlayOnly){ return true; }
|
||||
if(thisel.closest('.ui-headfoot-overlayonly').length){ return true; }
|
||||
|
||||
var fromTop = $.scrollY(),
|
||||
screenHeight = window.innerHeight,
|
||||
|
|
@ -36,121 +71,95 @@ $.fn.fixHeaderFooter = function(options){
|
|||
|
||||
return thisel.is('.ui-header') ? (thisTop + thisHeight <= fromTop) : (thisTop > fromTop + screenHeight);
|
||||
}
|
||||
|
||||
//set placeholder heights, then bind custom events
|
||||
els
|
||||
.each(function(){
|
||||
var placehold = $(this).parents('.ui-headfoot-placehold:eq(0)');
|
||||
if(o.overlayOnly){
|
||||
$(this).parent().parent().height(0);
|
||||
|
||||
|
||||
$(document)
|
||||
.bind('tap',function(e){
|
||||
if( !$(e.target).closest(ignoreTargets).length ){
|
||||
$.fixedToolbars.toggle();
|
||||
}
|
||||
})
|
||||
.bind('scrollstart',function(){
|
||||
if(currentstate == 'overlay'){
|
||||
showAfterScroll = true;
|
||||
}
|
||||
$.fixedToolbars.hide(true);
|
||||
})
|
||||
.bind('scrollstop',function(){
|
||||
if(showAfterScroll){
|
||||
$.fixedToolbars.show();
|
||||
showAfterScroll = false;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//hide on resize?
|
||||
$(window).resize(function(){ $.fixedToolbars.hide(true); });
|
||||
|
||||
|
||||
return {
|
||||
show: function(){
|
||||
if(currentstate == 'overlay'){ return; }
|
||||
currentstate = 'overlay';
|
||||
var els = allToolbars();
|
||||
return els.each(function(){
|
||||
var el = $(this),
|
||||
overlayOnly = el.closest('.ui-headfoot-overlayonly').length;
|
||||
el.parent().addClass('ui-fixpos');
|
||||
//only animate if placeholder is out of view
|
||||
if( placeHolderOutofView(el) ){
|
||||
el.addClass('in').animationComplete(function(){
|
||||
el.removeClass('in');
|
||||
});
|
||||
}
|
||||
if(overlayOnly){
|
||||
el.parent().parent().removeClass('ui-headfoot-hidden');
|
||||
}
|
||||
el.trigger('setTop');
|
||||
});
|
||||
},
|
||||
hide: function(immediately){
|
||||
if(currentstate == 'inline'){ return; }
|
||||
currentstate = 'inline';
|
||||
var els = allToolbars();
|
||||
return els.each(function(){
|
||||
var el = $(this),
|
||||
overlayOnly = el.closest('.ui-headfoot-overlayonly').length;
|
||||
|
||||
function addOverlayOnlyClass(){
|
||||
if(overlayOnly){
|
||||
el.parent().parent().addClass('ui-headfoot-hidden');
|
||||
}
|
||||
}
|
||||
//if immediately flag is true, or the placeholder is in view, don't animate the hide
|
||||
if(immediately || !placeHolderOutofView(el)){
|
||||
el.parent().removeClass('ui-fixpos');
|
||||
addOverlayOnlyClass();
|
||||
}
|
||||
else{
|
||||
$(this).parent().parent().height($(this).parent().height());
|
||||
}
|
||||
})
|
||||
.bind('setTop',function(){
|
||||
var fromTop = $.scrollY(),
|
||||
screenHeight = window.innerHeight,
|
||||
thisHeight = $(this).parent().outerHeight();
|
||||
return $(this).parent().css('top', ($(this).is('.ui-header')) ? fromTop : fromTop + screenHeight - thisHeight);
|
||||
})
|
||||
.bind('click tap mousedown',function(e){
|
||||
e.stopImmediatePropagation();
|
||||
return false;
|
||||
});
|
||||
|
||||
$uipage
|
||||
.bind('overlayIn',function(){
|
||||
console.log('out')
|
||||
currentstate = 'overlay';
|
||||
return els.each(function(){
|
||||
var el = $(this);
|
||||
el.parent().addClass('ui-fixpos');
|
||||
//only animate if placeholder is out of view
|
||||
if( placeHolderOutofView(el) ){
|
||||
el.addClass('in').animationComplete(function(){
|
||||
el.removeClass('in');
|
||||
});
|
||||
var classes = 'out';
|
||||
//if it's one of these, we'll need to add the reverse class too
|
||||
if(el.is('.slidedown,.slideup, .swap, .pop, .flip')){
|
||||
classes += ' reverse';
|
||||
}
|
||||
if(o.overlayOnly){
|
||||
el.parent().parent().removeClass('ui-headfoot-hidden');
|
||||
}
|
||||
el.trigger('setTop');
|
||||
});
|
||||
})
|
||||
.bind('overlayOut',function(e,immediately){
|
||||
console.log('in')
|
||||
currentstate = 'inline';
|
||||
return els.each(function(){
|
||||
var el = $(this);
|
||||
if(immediately || !placeHolderOutofView(el)){
|
||||
el.addClass(classes).animationComplete(function(){
|
||||
el.removeClass(classes);
|
||||
el.parent().removeClass('ui-fixpos');
|
||||
addOverlayOnlyClass();
|
||||
}
|
||||
else{
|
||||
var classes = 'out';
|
||||
//if it's one of these, we'll need to add the reverse class too
|
||||
if(el.is('.slidedown,.slideup, .swap, .pop, .flip')){
|
||||
classes += ' reverse';
|
||||
}
|
||||
el.addClass(classes).animationComplete(function(){
|
||||
el.removeClass(classes);
|
||||
el.parent().removeClass('ui-fixpos');
|
||||
addOverlayOnlyClass();
|
||||
});
|
||||
}
|
||||
function addOverlayOnlyClass(){
|
||||
if(o.overlayOnly){
|
||||
el.parent().parent().addClass('ui-headfoot-hidden');
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
.bind('overlayToggle',function(){
|
||||
return (currentstate == 'overlay') ? $(this).trigger('overlayOut') : $(this).trigger('overlayIn');
|
||||
});
|
||||
|
||||
|
||||
|
||||
$uipage
|
||||
.bind('tap',function(e){
|
||||
if( !$(e.target).closest(o.ignoreTargets).length ){
|
||||
$(this).trigger('overlayToggle');
|
||||
});
|
||||
}
|
||||
})
|
||||
.bind('scrollstart',function(){
|
||||
if(currentstate == 'overlay'){
|
||||
$uipage.data('visiblebeforescroll', true);
|
||||
}
|
||||
$uipage.trigger('overlayOut',[true]);
|
||||
return false;
|
||||
})
|
||||
.bind('scrollstop',function(){
|
||||
if($uipage.data('visiblebeforescroll')){
|
||||
$uipage.removeData('visiblebeforescroll').trigger('overlayIn');
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
},
|
||||
hideAfterDelay: function(){
|
||||
delayTimer = setTimeout(function(){
|
||||
$.fixedToolbars.hide();
|
||||
}, 3000);
|
||||
},
|
||||
toggle: function(){
|
||||
return (currentstate == 'overlay') ? $.fixedToolbars.hide() : $.fixedToolbars.show();
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
$('body').scrollstart(function(){
|
||||
$uipage.trigger('scrollstart');
|
||||
})
|
||||
.scrollstop(function(){
|
||||
$uipage.trigger('scrollstop');
|
||||
});
|
||||
|
||||
|
||||
$(window)
|
||||
.bind('load',function(){
|
||||
$uipage.trigger('overlayIn');
|
||||
|
||||
if(o.overlayOnly){
|
||||
//to-do...for a photo-viewer or something full-screen
|
||||
els.parents('.ui-headfoot-placehold:eq(0)').addClass('ui-headfoot-overlayonly');
|
||||
}
|
||||
})
|
||||
.resize(function(){ $uipage.trigger('overlayOut',[true]); });
|
||||
});
|
||||
};
|
||||
})(jQuery);
|
||||
|
|
@ -25,11 +25,12 @@
|
|||
prevUrl = location.hash,
|
||||
//vars for custom event tracking
|
||||
scrolling = false,
|
||||
scrollListeningOn = true,
|
||||
touching = false,
|
||||
touchstartdata,
|
||||
touchstopdata,
|
||||
tapNotMoveTime = 50,
|
||||
tapHoldTime = 700,
|
||||
tapNotMoveTime = 75,
|
||||
tapHoldTime = 300,
|
||||
maxSwipeTime = 1000,
|
||||
minSwipeXDistance = 180,
|
||||
maxSwipeYtolerance = 80;
|
||||
|
|
@ -153,7 +154,11 @@
|
|||
//hide Address bar
|
||||
function hideBrowserChrome(){
|
||||
//kill addr bar
|
||||
scrollListeningOn = false;
|
||||
window.scrollTo(0,0);
|
||||
setTimeout(function(){
|
||||
scrollListeningOn = true;
|
||||
}, 150);
|
||||
}
|
||||
|
||||
//get vert scroll dist
|
||||
|
|
@ -177,10 +182,11 @@
|
|||
|
||||
//detect and trigger some custom events (scrollstart,scrollstop,tap,taphold,swipe,swipeleft,swiperight)
|
||||
$(document)
|
||||
.scroll(function(e){
|
||||
.scroll(function(e){
|
||||
if(!scrollListeningOn){ return false; }
|
||||
var prevscroll = $.scrollY();
|
||||
function checkscrollstop(){
|
||||
if(prevscroll === $.scrollY() && scrolling){
|
||||
if(prevscroll === $.scrollY() && scrolling && scrollListeningOn){
|
||||
$body.trigger('scrollstop');
|
||||
scrolling = false;
|
||||
}
|
||||
|
|
@ -188,6 +194,7 @@
|
|||
setTimeout(checkscrollstop,50);
|
||||
})
|
||||
.bind( ($.support.touch ? 'touchmove' : 'scroll'), function(e){
|
||||
if(!scrollListeningOn){ return false; }
|
||||
//iPhone triggers scroll a tad late - touchmoved preferred
|
||||
if(!scrolling){
|
||||
scrolling = true;
|
||||
|
|
@ -294,7 +301,6 @@
|
|||
//turn on/off page loading message.. also hides the ui-content div
|
||||
function pageLoading(done){
|
||||
if(done){
|
||||
hideToolbarsAfterDelay();
|
||||
//remove loading msg
|
||||
$html.removeClass('ui-loading');
|
||||
//fade in page content, remove loading msg
|
||||
|
|
@ -309,7 +315,6 @@
|
|||
//transition between pages - based on transitions from jQtouch
|
||||
function changePage(from,to,back){
|
||||
hideBrowserChrome();
|
||||
|
||||
if(!back && !transitionSpecified){ currentTransition = 'slide'; }
|
||||
|
||||
//kill keyboard (thx jQtouch :) )
|
||||
|
|
@ -323,8 +328,9 @@
|
|||
to.animationComplete(function(){
|
||||
from.add(to).removeClass(' out in reverse '+ transitions);
|
||||
from.removeClass(activePageClass);
|
||||
to.trigger('overlayIn');
|
||||
pageLoading(true);
|
||||
$.fixedToolbars.show();
|
||||
$.fixedToolbars.hideAfterDelay();
|
||||
});
|
||||
if(back){ currentTransition = 'slide'; }
|
||||
};
|
||||
|
|
@ -341,14 +347,11 @@
|
|||
}
|
||||
};
|
||||
|
||||
function hideToolbarsAfterDelay(){
|
||||
setTimeout(function(){
|
||||
$('.ui-page-active').trigger('overlayOut');
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
|
||||
//markup-driven enhancements, to be called on any ui-page upon loading
|
||||
function mobilize($el){
|
||||
//to-do: make sure this only runs one time on a page (or maybe per component)
|
||||
return $el.each(function(){
|
||||
//checkboxes, radios
|
||||
$el.find('input[type=radio],input[type=checkbox]').customCheckboxRadio();
|
||||
|
|
@ -434,12 +437,15 @@
|
|||
changePage(currentPage, startPage, back);
|
||||
}
|
||||
else{
|
||||
$.fixedToolbars.show();
|
||||
startPage.addClass(activePageClass);
|
||||
startPage.trigger('overlayIn');
|
||||
pageLoading(true);
|
||||
$.fixedToolbars.hideAfterDelay();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
hideBrowserChrome();
|
||||
|
||||
//mobilize all pages present
|
||||
mobilize($('.ui-page'));
|
||||
|
|
|
|||
Loading…
Reference in a new issue