You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
5.5 KiB
170 lines
5.5 KiB
define([ |
|
"dojo/_base/array", |
|
"dojo/_base/declare", |
|
"dojo/dom-class", |
|
"dojo/dom-construct", |
|
"dijit/registry", // registry.byNode |
|
"./View", |
|
"./_ScrollableMixin" |
|
], function(array, declare, domClass, domConstruct, registry, View, ScrollableMixin){ |
|
|
|
// module: |
|
// dojox/mobile/ScrollableView |
|
|
|
return declare("dojox.mobile.ScrollableView", [View, ScrollableMixin], { |
|
// summary: |
|
// A container that has a touch scrolling capability. |
|
// description: |
|
// ScrollableView is a subclass of View (dojox/mobile/View). |
|
// Unlike the base View class, ScrollableView's domNode always stays |
|
// at the top of the screen and its height is "100%" of the screen. |
|
// Inside this fixed domNode, the containerNode scrolls. The browser's |
|
// default scrolling behavior is disabled, and the scrolling mechanism is |
|
// reimplemented in JavaScript. Thus the user does not need to use the |
|
// two-finger operation to scroll the inner DIV (containerNode). |
|
// The main purpose of this widget is to realize fixed-positioned header |
|
// and/or footer bars. |
|
|
|
// scrollableParams: Object |
|
// Parameters for dojox/mobile/scrollable.init(). |
|
scrollableParams: null, |
|
|
|
// keepScrollPos: Boolean |
|
// Overrides dojox/mobile/View/keepScrollPos. |
|
keepScrollPos: false, |
|
|
|
constructor: function(){ |
|
// summary: |
|
// Creates a new instance of the class. |
|
this.scrollableParams = {noResize: true}; |
|
}, |
|
|
|
buildRendering: function(){ |
|
this.inherited(arguments); |
|
domClass.add(this.domNode, "mblScrollableView"); |
|
this.domNode.style.overflow = "hidden"; |
|
this.domNode.style.top = "0px"; |
|
this.containerNode = domConstruct.create("div", |
|
{className:"mblScrollableViewContainer"}, this.domNode); |
|
this.containerNode.style.position = "absolute"; |
|
this.containerNode.style.top = "0px"; // view bar is relative |
|
if(this.scrollDir === "v"){ |
|
this.containerNode.style.width = "100%"; |
|
} |
|
}, |
|
|
|
startup: function(){ |
|
if(this._started){ return; } |
|
// user can initialize the app footers using a value for fixedFooter (we keep this value for non regression of existing apps) |
|
if(this.fixedFooter && !this.isLocalFooter){ |
|
this._fixedAppFooter = this.fixedFooter; |
|
this.fixedFooter = ""; |
|
} |
|
this.reparent(); |
|
this.inherited(arguments); |
|
}, |
|
|
|
resize: function(){ |
|
// summary: |
|
// Calls resize() of each child widget. |
|
this.inherited(arguments); // scrollable#resize() will be called |
|
array.forEach(this.getChildren(), function(child){ |
|
if(child.resize){ child.resize(); } |
|
}); |
|
this._dim = this.getDim(); // update dimension cache |
|
if(this._conn){ |
|
// if a resize happens during a scroll, update the scrollbar |
|
this.resetScrollBar(); |
|
} |
|
}, |
|
|
|
isTopLevel: function(/*Event*/e){ |
|
// summary: |
|
// Returns true if this is a top-level widget. |
|
// Overrides dojox/mobile/scrollable.isTopLevel. |
|
var parent = this.getParent && this.getParent(); |
|
return (!parent || !parent.resize); // top level widget |
|
}, |
|
|
|
addFixedBar: function(/*Widget*/widget){ |
|
// summary: |
|
// Adds a view local fixed bar to this widget. |
|
// description: |
|
// This method can be used to programmatically add a view local |
|
// fixed bar to ScrollableView. The bar is appended to this |
|
// widget's domNode. The addChild API cannot be used for this |
|
// purpose, because it adds the given widget to containerNode. |
|
var c = widget.domNode; |
|
var fixed = this.checkFixedBar(c, true); |
|
if(!fixed){ return; } |
|
// Fixed bar has to be added to domNode, not containerNode. |
|
this.domNode.appendChild(c); |
|
if(fixed === "top"){ |
|
this.fixedHeaderHeight = c.offsetHeight; |
|
this.isLocalHeader = true; |
|
}else if(fixed === "bottom"){ |
|
this.fixedFooterHeight = c.offsetHeight; |
|
this.isLocalFooter = true; |
|
c.style.bottom = "0px"; |
|
} |
|
this.resize(); |
|
}, |
|
|
|
reparent: function(){ |
|
// summary: |
|
// Moves all the children, except header and footer, to |
|
// containerNode. |
|
var i, idx, len, c; |
|
for(i = 0, idx = 0, len = this.domNode.childNodes.length; i < len; i++){ |
|
c = this.domNode.childNodes[idx]; |
|
// search for view-specific header or footer |
|
if(c === this.containerNode || this.checkFixedBar(c, true)){ |
|
idx++; |
|
continue; |
|
} |
|
this.containerNode.appendChild(this.domNode.removeChild(c)); |
|
} |
|
}, |
|
|
|
onAfterTransitionIn: function(moveTo, dir, transition, context, method){ |
|
// summary: |
|
// Overrides View.onAfterTransitionIn to flash the scroll bar |
|
// after performing a view transition. |
|
this.flashScrollBar(); |
|
}, |
|
|
|
getChildren: function(){ |
|
// summary: |
|
// Overrides _WidgetBase.getChildren to add local fixed bars, |
|
// which are not under containerNode, to the children array. |
|
var children = this.inherited(arguments); |
|
var fixedWidget; |
|
if(this.fixedHeader && this.fixedHeader.parentNode === this.domNode){ |
|
fixedWidget = registry.byNode(this.fixedHeader); |
|
if(fixedWidget){ |
|
children.push(fixedWidget); |
|
} |
|
} |
|
if(this.fixedFooter && this.fixedFooter.parentNode === this.domNode){ |
|
fixedWidget = registry.byNode(this.fixedFooter); |
|
if(fixedWidget){ |
|
children.push(fixedWidget); |
|
} |
|
} |
|
return children; |
|
}, |
|
|
|
_addTransitionPaddingTop: function(/*String|Integer*/ value){ |
|
// add padding top to the view in order to get alignment during the transition |
|
this.domNode.style.paddingTop = value + "px"; |
|
this.containerNode.style.paddingTop = value + "px"; |
|
}, |
|
|
|
_removeTransitionPaddingTop: function(){ |
|
// remove padding top from the view after the transition |
|
this.domNode.style.paddingTop = ""; |
|
this.containerNode.style.paddingTop = ""; |
|
} |
|
|
|
}); |
|
});
|
|
|