ScrollPane.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojox.layout.ScrollPane"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.layout.ScrollPane"] = true;
  8. dojo.provide("dojox.layout.ScrollPane");
  9. dojo.experimental("dojox.layout.ScrollPane");
  10. dojo.require("dijit.layout.ContentPane");
  11. dojo.require("dijit._Templated");
  12. dojo.declare("dojox.layout.ScrollPane",
  13. [dijit.layout.ContentPane, dijit._Templated],
  14. {
  15. // summary: A pane that "scrolls" its content based on the mouse poisition inside
  16. //
  17. // description:
  18. // A sizable container that takes it's content's natural size and creates
  19. // a scroll effect based on the relative mouse position. It is an interesting
  20. // way to display lists of data, or blocks of content, within a confined
  21. // space.
  22. //
  23. // Horizontal scrolling is supported. Combination scrolling is not.
  24. //
  25. // FIXME: need to adust the _line somehow, it stops scrolling
  26. //
  27. // example:
  28. // | <div dojoType="dojox.layout.ScrollPane" style="width:150px height:300px;">
  29. // | <!-- any height content -->
  30. // | </div>
  31. //
  32. // _line: dojo._Line
  33. // storage for our top and bottom most scrollpoints
  34. _line: null,
  35. // _lo: the height of the visible pane
  36. _lo: null,
  37. _offset: 15,
  38. // orientation: String
  39. // either "horizontal" or "vertical" for scroll orientation.
  40. orientation: "vertical",
  41. // alwaysShow: Boolean
  42. // whether the scroll helper should hide when mouseleave
  43. autoHide: true,
  44. templateString: dojo.cache("dojox.layout", "resources/ScrollPane.html", "<div class=\"dojoxScrollWindow\" dojoAttachEvent=\"onmouseenter: _enter, onmouseleave: _leave\">\n <div class=\"dojoxScrollWrapper\" style=\"${style}\" dojoAttachPoint=\"wrapper\" dojoAttachEvent=\"onmousemove: _calc\">\n\t<div class=\"dojoxScrollPane\" dojoAttachPoint=\"containerNode\"></div>\n </div>\n <div dojoAttachPoint=\"helper\" class=\"dojoxScrollHelper\"><span class=\"helperInner\">|</span></div>\n</div>\n"),
  45. resize: function(size){
  46. // summary: calculates required sizes. Call this if you add/remove content manually, or reload the content.
  47. // if size is passed, it means we need to take care of sizing ourself (this is for IE<8)
  48. if(size){
  49. if(size.h){
  50. dojo.style(this.domNode,'height',size.h+'px');
  51. }
  52. if(size.w){
  53. dojo.style(this.domNode,'width',size.w+'px');
  54. }
  55. }
  56. var dir = this._dir,
  57. vert = this._vertical,
  58. val = this.containerNode[(vert ? "scrollHeight" : "scrollWidth")];
  59. dojo.style(this.wrapper, this._dir, this.domNode.style[this._dir]);
  60. this._lo = dojo.coords(this.wrapper, true);
  61. this._size = Math.max(0, val - this._lo[(vert ? "h" : "w")]);
  62. if(!this._size){
  63. this.helper.style.display="none";
  64. //make sure we reset scroll position, otherwise the content may be hidden
  65. this.wrapper[this._scroll]=0;
  66. return;
  67. }else{
  68. this.helper.style.display="";
  69. }
  70. this._line = new dojo._Line(0 - this._offset, this._size + (this._offset * 2));
  71. // share a relative position w the scroll offset via a line
  72. var u = this._lo[(vert ? "h" : "w")],
  73. r = Math.min(1, u / val), // ratio
  74. s = u * r, // size
  75. c = Math.floor(u - (u * r)); // center
  76. this._helpLine = new dojo._Line(0, c);
  77. // size the helper
  78. dojo.style(this.helper, dir, Math.floor(s) + "px");
  79. },
  80. postCreate: function(){
  81. this.inherited(arguments);
  82. // for the helper
  83. if(this.autoHide){
  84. this._showAnim = dojo._fade({ node:this.helper, end:0.5, duration:350 });
  85. this._hideAnim = dojo.fadeOut({ node:this.helper, duration: 750 });
  86. }
  87. // orientation helper
  88. this._vertical = (this.orientation == "vertical");
  89. if(!this._vertical){
  90. dojo.addClass(this.containerNode,"dijitInline");
  91. this._dir = "width";
  92. this._edge = "left";
  93. this._scroll = "scrollLeft";
  94. }else{
  95. this._dir = "height";
  96. this._edge = "top";
  97. this._scroll = "scrollTop";
  98. }
  99. if(this._hideAnim){
  100. this._hideAnim.play();
  101. }
  102. dojo.style(this.wrapper,"overflow","hidden");
  103. },
  104. _set: function(/* Float */n){
  105. if(!this._size){ return; }
  106. // summary: set the pane's scroll offset, and position the virtual scroll helper
  107. this.wrapper[this._scroll] = Math.floor(this._line.getValue(n));
  108. dojo.style(this.helper, this._edge, Math.floor(this._helpLine.getValue(n)) + "px");
  109. },
  110. _calc: function(/* Event */e){
  111. // summary: calculate the relative offset of the cursor over the node, and call _set
  112. if(!this._lo){ this.resize(); }
  113. this._set(this._vertical ?
  114. ((e.pageY - this._lo.y) / this._lo.h) :
  115. ((e.pageX - this._lo.x) / this._lo.w)
  116. );
  117. },
  118. _enter: function(e){
  119. if(this._hideAnim){
  120. if(this._hideAnim.status() == "playing"){
  121. this._hideAnim.stop();
  122. }
  123. this._showAnim.play();
  124. }
  125. },
  126. _leave: function(e){
  127. if(this._hideAnim){
  128. this._hideAnim.play();
  129. }
  130. }
  131. });
  132. }