ScrollableView.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. define("dojox/mobile/ScrollableView", [
  2. "dojo/_base/array",
  3. "dojo/_base/declare",
  4. "dojo/dom-class",
  5. "dojo/dom-construct",
  6. "dijit/registry", // registry.byNode
  7. "./View",
  8. "./_ScrollableMixin"
  9. ], function(array, declare, domClass, domConstruct, registry, View, ScrollableMixin){
  10. /*=====
  11. var View = dojox.mobile.View;
  12. var ScrollableMixin = dojox.mobile._ScrollableMixin;
  13. =====*/
  14. // module:
  15. // dojox/mobile/ScrollableView
  16. // summary:
  17. // A container that has a touch scrolling capability.
  18. return declare("dojox.mobile.ScrollableView", [View, ScrollableMixin], {
  19. // summary:
  20. // A container that has a touch scrolling capability.
  21. // description:
  22. // ScrollableView is a subclass of View (=dojox.mobile.View).
  23. // Unlike the base View class, ScrollableView's domNode always stays
  24. // at the top of the screen and its height is "100%" of the screen.
  25. // In this fixed domNode, containerNode scrolls. Browser's default
  26. // scrolling behavior is disabled, and the scrolling machinery is
  27. // re-implemented with JavaScript. Thus the user does not need to use the
  28. // two-finger operation to scroll an inner DIV (containerNode).
  29. // The main purpose of this widget is to realize fixed-positioned header
  30. // and/or footer bars.
  31. // scrollableParams: Object
  32. // Parameters for dojox.mobile.scrollable.init().
  33. scrollableParams: null,
  34. // keepScrollPos: Boolean
  35. // Overrides dojox.mobile.View.keepScrollPos.
  36. keepScrollPos: false,
  37. constructor: function(){
  38. this.scrollableParams = {noResize: true};
  39. },
  40. buildRendering: function(){
  41. this.inherited(arguments);
  42. domClass.add(this.domNode, "mblScrollableView");
  43. this.domNode.style.overflow = "hidden";
  44. this.domNode.style.top = "0px";
  45. this.containerNode = domConstruct.create("DIV",
  46. {className:"mblScrollableViewContainer"}, this.domNode);
  47. this.containerNode.style.position = "absolute";
  48. this.containerNode.style.top = "0px"; // view bar is relative
  49. if(this.scrollDir === "v"){
  50. this.containerNode.style.width = "100%";
  51. }
  52. this.reparent();
  53. this.findAppBars();
  54. },
  55. resize: function(){
  56. // summary:
  57. // Calls resize() of each child widget.
  58. this.inherited(arguments); // scrollable#resize() will be called
  59. array.forEach(this.getChildren(), function(child){
  60. if(child.resize){ child.resize(); }
  61. });
  62. },
  63. isTopLevel: function(e){
  64. // summary:
  65. // Returns true if this is a top-level widget.
  66. // Overrides dojox.mobile.scrollable.
  67. var parent = this.getParent && this.getParent();
  68. return (!parent || !parent.resize); // top level widget
  69. },
  70. addChild: function(widget, /*Number?*/insertIndex){
  71. var c = widget.domNode;
  72. var fixed = this.checkFixedBar(c, true);
  73. if(fixed){
  74. // Addition of a fixed bar is an exceptional case.
  75. // It has to be added to domNode, not containerNode.
  76. // In this case, insertIndex is ignored.
  77. this.domNode.appendChild(c);
  78. if(fixed === "top"){
  79. this.fixedHeaderHeight = c.offsetHeight;
  80. this.isLocalHeader = true;
  81. }else if(fixed === "bottom"){
  82. this.fixedFooterHeight = c.offsetHeight;
  83. this.isLocalFooter = true;
  84. c.style.bottom = "0px";
  85. }
  86. this.resize();
  87. if(this._started && !widget._started){
  88. widget.startup();
  89. }
  90. }else{
  91. this.inherited(arguments);
  92. }
  93. },
  94. reparent: function(){
  95. // summary:
  96. // Moves all the children, except header and footer, to
  97. // containerNode.
  98. var i, idx, len, c;
  99. for(i = 0, idx = 0, len = this.domNode.childNodes.length; i < len; i++){
  100. c = this.domNode.childNodes[idx];
  101. // search for view-specific header or footer
  102. if(c === this.containerNode || this.checkFixedBar(c, true)){
  103. idx++;
  104. continue;
  105. }
  106. this.containerNode.appendChild(this.domNode.removeChild(c));
  107. }
  108. },
  109. onAfterTransitionIn: function(moveTo, dir, transition, context, method){
  110. this.flashScrollBar();
  111. },
  112. getChildren: function(){
  113. // summary:
  114. // Overrides _WidgetBase#getChildren to add local fixed bars,
  115. // which are not under containerNode, to the children array.
  116. var children = this.inherited(arguments);
  117. if(this.fixedHeader && this.fixedHeader.parentNode === this.domNode){
  118. children.push(registry.byNode(this.fixedHeader));
  119. }
  120. if(this.fixedFooter && this.fixedFooter.parentNode === this.domNode){
  121. children.push(registry.byNode(this.fixedFooter));
  122. }
  123. return children;
  124. }
  125. });
  126. });