ScrollBar.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. o2.widget = o2.widget || {};
  2. o2.require("o2.widget.Common", null, false);
  3. o2.widget.ScrollBar = new Class({
  4. Implements : [ Options, Events],
  5. Extends: o2.widget.Common,
  6. options : {
  7. "distance" : 50,
  8. "style": "default",
  9. "isShow": false,
  10. "where": "before",
  11. "indent": true,
  12. "offset": {
  13. "V": {
  14. "x": 0,
  15. "y": 0
  16. },
  17. "H": {
  18. "x": 0,
  19. "y": 0
  20. }
  21. }
  22. },
  23. scrollEvent: function(node){
  24. var scrollTop = node.scrollTop.toFloat();
  25. var scrollLeft = node.scrollLeft.toFloat();
  26. this.fireEvent("scroll", [scrollTop, scrollLeft]);
  27. },
  28. initialize : function(node, options) {
  29. if (COMMON.Browser.Platform.isMobile){
  30. node.setStyle("overflow", "auto");
  31. node.addEvent("scroll", function(){
  32. this.scrollEvent(node);
  33. }.bind(this));
  34. // node.addEvent("touchstart", function(e){ this.checkScroll()}.bind(this));
  35. // node.addEvent("touchmove", function(e){
  36. // e.preventDefault();
  37. // // this.fireEvent("scroll", [1]);
  38. // // e.preventDefault();
  39. // //
  40. // // var scrollTop = node.scrollTop.toFloat();
  41. // // var scrollLeft = node.scrollLeft.toFloat();
  42. // // //this.fireEvent("scroll", [scrollTop, scrollLeft]);
  43. // e.stopPropagation();
  44. // }.bind(this));
  45. // node.addEvent("touchend", function(e){
  46. // this.scrollEvent(node);
  47. // }.bind(this));
  48. return true;
  49. }
  50. this.node = $(node);
  51. this.setOptions(options);
  52. this.path = o2.session.path+"/widget/$ScrollBar/";
  53. this.cssPath = o2.session.path+"/widget/$ScrollBar/"+this.options.style+"/css.wcss";
  54. this._loadCss();
  55. document.body.onresize = function(e){
  56. this.checkScroll();
  57. }.bind(this);
  58. this.node.onresize = function(e){
  59. this.checkScroll();
  60. }.bind(this);
  61. this.node.addEvent("mouseover", function(e){
  62. this.checkScroll();
  63. e.stopPropagation();
  64. }.bind(this));
  65. this.node.addEvent("mouseout", function(e){
  66. this.checkScroll();
  67. e.stopPropagation();
  68. }.bind(this));
  69. // this.node.addEvent("click", function(e){
  70. // this.checkScrollShow(e);
  71. // }.bind(this));
  72. this.checkScrollShow();
  73. document.body.addEvent("mousemove", function(e){
  74. this.checkScrollShow(e);
  75. }.bind(this));
  76. // this.node.getChildren().each(function(node){
  77. // node.onresize = function(e){
  78. // this.checkScroll();
  79. // }.bind(this);
  80. // }.bind(this));
  81. // this.node.onpropertychange = function(e){
  82. // this.checkScroll();
  83. // }.bind(this);
  84. },
  85. checkScrollShow: function(e){
  86. if (!this.node.isPointIn) return false;
  87. //if (this.node.isPointIn(e.event.clientX, e.event.clientY, this.scrollVWidth)){
  88. if (this.scrollVAreaNode){
  89. var opacity = this.scrollVAreaNode.getStyle("opacity");
  90. if (opacity==0){
  91. if (!this.scrollAreaOverLock && !this.scrollAreaOutLock){
  92. this.scrollAreaOverLock = true;
  93. var margin = this.node.getStyle("margin-right").toFloat();
  94. if (this.options.indent){
  95. var marginFx = new Fx.Tween(this.node, {property: "margin-right", duration: "100"});
  96. marginFx.start(margin+this.scrollVWidth).chain(function(){
  97. this.scrollVAreaNode.setStyle("display", "block");
  98. var scrollFx = new Fx.Tween(this.scrollVAreaNode, {property: "opacity", duration: "100"});
  99. scrollFx.start(0,1).chain(function(){
  100. this.scrollAreaOverLock = false;
  101. }.bind(this));
  102. //this.scrollVAreaNode.fade("in");
  103. }.bind(this));
  104. }else{
  105. this.scrollVAreaNode.setStyle("display", "block");
  106. var scrollFx = new Fx.Tween(this.scrollVAreaNode, {property: "opacity", duration: "100"});
  107. scrollFx.start(0,1).chain(function(){
  108. this.scrollAreaOverLock = false;
  109. }.bind(this));
  110. }
  111. }
  112. }
  113. }
  114. // }else{
  115. // if (this.scrollVAreaNode){
  116. // var opacity = this.scrollVAreaNode.getStyle("opacity");
  117. // // if (!this.options.isShow){
  118. // if (opacity==1){
  119. // if (!this.scrollAreaOutLock && !this.scrollAreaOverLock){
  120. // if (!this.showScrollBar){
  121. // this.scrollAreaOutLock = true;
  122. // var scrollFx = new Fx.Tween(this.scrollVAreaNode, {property: "opacity", duration: "100"});
  123. // scrollFx.start(0).chain(function(){
  124. // var margin = this.node.getStyle("margin-right").toFloat();
  125. // this.scrollVAreaNode.setStyle("display", "none");
  126. // if (this.options.indent){
  127. // var marginFx = new Fx.Tween(this.node, {property: "margin-right", duration: "100"});
  128. // marginFx.start(margin-this.scrollVWidth).chain(function(){
  129. // this.scrollAreaOutLock = false;
  130. // }.bind(this));
  131. // }else{
  132. // this.scrollAreaOutLock = false;
  133. // }
  134. // }.bind(this));
  135. // }
  136. // }
  137. // }
  138. // // }
  139. // }
  140. // }
  141. },
  142. // checkScrollShow: function(e){
  143. // if (!this.node.isPointIn) return false;
  144. // if (this.node.isPointIn(e.event.clientX, e.event.clientY, this.scrollVWidth)){
  145. // if (this.scrollVAreaNode){
  146. // var opacity = this.scrollVAreaNode.getStyle("opacity");
  147. // if (opacity==0){
  148. // if (!this.scrollAreaOverLock && !this.scrollAreaOutLock){
  149. // this.scrollAreaOverLock = true;
  150. // var margin = this.node.getStyle("margin-right").toFloat();
  151. // if (this.options.indent){
  152. // var marginFx = new Fx.Tween(this.node, {property: "margin-right", duration: "100"});
  153. // marginFx.start(margin+this.scrollVWidth).chain(function(){
  154. // this.scrollVAreaNode.setStyle("display", "block");
  155. //
  156. // var scrollFx = new Fx.Tween(this.scrollVAreaNode, {property: "opacity", duration: "100"});
  157. // scrollFx.start(0,1).chain(function(){
  158. // this.scrollAreaOverLock = false;
  159. // }.bind(this));
  160. //
  161. // //this.scrollVAreaNode.fade("in");
  162. //
  163. // }.bind(this));
  164. // }else{
  165. // this.scrollVAreaNode.setStyle("display", "block");
  166. //
  167. // var scrollFx = new Fx.Tween(this.scrollVAreaNode, {property: "opacity", duration: "100"});
  168. // scrollFx.start(0,1).chain(function(){
  169. // this.scrollAreaOverLock = false;
  170. // }.bind(this));
  171. // }
  172. // }
  173. // }
  174. // }
  175. // }else{
  176. // if (this.scrollVAreaNode){
  177. // var opacity = this.scrollVAreaNode.getStyle("opacity");
  178. // // if (!this.options.isShow){
  179. // if (opacity==1){
  180. // if (!this.scrollAreaOutLock && !this.scrollAreaOverLock){
  181. // if (!this.showScrollBar){
  182. // this.scrollAreaOutLock = true;
  183. // var scrollFx = new Fx.Tween(this.scrollVAreaNode, {property: "opacity", duration: "100"});
  184. // scrollFx.start(0).chain(function(){
  185. // var margin = this.node.getStyle("margin-right").toFloat();
  186. // this.scrollVAreaNode.setStyle("display", "none");
  187. // if (this.options.indent){
  188. // var marginFx = new Fx.Tween(this.node, {property: "margin-right", duration: "100"});
  189. // marginFx.start(margin-this.scrollVWidth).chain(function(){
  190. // this.scrollAreaOutLock = false;
  191. // }.bind(this));
  192. // }else{
  193. // this.scrollAreaOutLock = false;
  194. // }
  195. // }.bind(this));
  196. // }
  197. // }
  198. // }
  199. // // }
  200. // }
  201. // }
  202. // },
  203. setScrollNodePosition: function(){
  204. this.node.scrollTo(0,0);
  205. if (this.scrollVNode){
  206. // var x = (this.clientSize.x.toFloat()) - (this.scrollVNodeSize.x.toFloat()) + this.options.offset.V.x;
  207. // var y = 0-(this.scrollSize.y.toFloat()) + this.options.offset.V.y;
  208. // this.scrollVNode.setStyle("margin-left", ""+x+"px");
  209. this.scrollVNode.setStyle("margin-top", "0px");
  210. // this.scrollVNode.setStyle("margin-left", "100px");
  211. // this.scrollVNode.setStyle("margin-top", ""+y+"px");
  212. this.setScrollVNodeMoveLimit();
  213. }
  214. if (this.scrollHNode){
  215. // var x = (this.nodePosition.x.toFloat());
  216. // //var y = (this.nodePosition.y.toFloat())+(this.clientSize.y.toFloat())-(this.scrollVNodeSize.y.toFloat());
  217. // var y = (this.nodePosition.y.toFloat())+(this.clientSize.y.toFloat());
  218. // this.scrollHNode.setStyle("top", ""+y+"px");
  219. // this.scrollHNode.setStyle("left", ""+x+"px");
  220. var y = this.scrollHNode.getSize().y;
  221. y = 0-y + this.options.offset.H.y;
  222. var x = 0 + this.options.offset.H.x;
  223. this.scrollHNode.setStyle("margin-left", ""+x+"px");
  224. this.scrollHNode.setStyle("margin-top", ""+y+"px");
  225. }
  226. },
  227. setScrollVNodeMove: function(){
  228. this.scrollVAreaNode.addEvent("click", function(e){e.stopPropagation();});
  229. this.scrollVNodeMove = new Drag(this.scrollVNode,{
  230. "onStart": function(el, e){
  231. this.fireEvent("scrollStart");
  232. var x = e.event.clientX;
  233. var y = e.event.clientY;
  234. el.store("position", {"x": x, "y": y});
  235. el.store("margin", el.getStyle("margin-top"));
  236. this.showScrollBar = true;
  237. }.bind(this),
  238. "onComplete": function(e){
  239. this.showScrollBar = false;
  240. this.fireEvent("scrollComplete");
  241. }.bind(this),
  242. "onDrag": function(el, e){
  243. var p = el.retrieve("position");
  244. var margin = el.retrieve("margin").toFloat();
  245. // var dx = (e.event.clientX.toFloat()) - (p.x.toFloat());
  246. var dy = (e.event.clientY.toFloat()) - (p.y.toFloat());
  247. var dmargin = margin+dy;
  248. var scrollSize = this.node.getScrollSize();
  249. var clientSize = this.node.getSize();
  250. var scrollVNodeSize = this.scrollVNode.getSize();
  251. //var marginTop = this.node.getStyle("margin-top").toFloat();
  252. var maxY = (clientSize.y.toFloat())-(scrollVNodeSize.y.toFloat());
  253. var minY = 0;
  254. if (dmargin<minY) dmargin = minY;
  255. if (dmargin>maxY) dmargin = maxY;
  256. this.scrollVNode.setStyle("margin-top", ""+dmargin+"px");
  257. this.scroll(null, dmargin);
  258. // var vPosition = this.scrollVNode.getPosition();
  259. // this.scroll(null, (vPosition.y.toFloat())-(this.nodePosition.y.toFloat()));
  260. }.bind(this)
  261. });
  262. },
  263. setScrollVNodeMoveLimit: function(){
  264. //var x = (this.nodePosition.x.toFloat())+(this.clientSize.x.toFloat())-(this.scrollVNodeSize.x.toFloat());
  265. var x = (this.nodePosition.x.toFloat())+(this.clientSize.x.toFloat());
  266. var y = (this.nodePosition.y.toFloat());
  267. var maxY = y+(this.clientSize.y.toFloat()) - (this.scrollVNodeSize.y.toFloat());
  268. this.scrollVNodeMove.detach();
  269. this.scrollVNodeMove.setOptions({"limit": {"x": [x, x], "y": [y, maxY]}});
  270. this.scrollVNodeMove.attach();
  271. },
  272. scroll: function(nodeDelta, scrollDelta){
  273. var scrollSize = this.node.getScrollSize();
  274. var clientSize = this.node.getSize();
  275. var scrollVNodeSize = this.scrollVNode.getSize();
  276. // var marginTop = this.node.getStyle("margin-top").toFloat();
  277. var scrollHeight = scrollSize.y-clientSize.y;
  278. var maxY = (clientSize.y.toFloat())-(scrollVNodeSize.y.toFloat());
  279. var minY = 0;
  280. if (nodeDelta){
  281. var scroll = this.node.getScroll();
  282. var scrollTo = (scroll.y.toFloat())+(nodeDelta.toFloat());
  283. if (scrollTo<0) scrollTo = 0;
  284. if (scrollTo>scrollHeight) scrollTo = scrollHeight;
  285. //this.node.scrollTo(0, scrollTo);
  286. this.fireEvent("scroll", [scrollTo]);
  287. this.node.tweenScroll(scrollTo, 1);
  288. //this.node.tween("margin-top", -100);
  289. var y = (scrollTo/(scrollHeight.toFloat()))*(maxY.toFloat());
  290. if (y<minY) y = minY;
  291. if (y>maxY) y = maxY;
  292. // this.scrollVNode.set("tween", {"duration": "1", "transition": Fx.Transitions.Expo.easeOut});
  293. // this.scrollVNode.tween("margin-top", ""+y+"px");
  294. this.scrollVNode.setStyle("margin-top", ""+y+"px");
  295. }
  296. if (scrollDelta){
  297. if (scrollDelta>maxY) scrollDelta = maxY;
  298. var y = (scrollDelta/maxY)*scrollHeight;
  299. var scroll = this.node.getScroll();
  300. //this.node.scrollTo(0, y);
  301. this.node.tweenScroll(y, 1);
  302. this.fireEvent("scroll", [y]);
  303. }
  304. },
  305. checkScroll: function(){
  306. var scrollSize = this.node.getScrollSize();
  307. var clientSize = this.node.getSize();
  308. var nodePosition = this.node.getPosition(this.node.getOffsetParent());
  309. this.mousewheel = function(e){
  310. var delta = 1-e.event.wheelDelta;
  311. var step = ((this.options.distance.toFloat())/100)*(clientSize.y.toFloat());
  312. delta = (delta/(clientSize.y.toFloat()))*step;
  313. this.scroll(delta, null);
  314. e.stopPropagation();
  315. }.bind(this);
  316. this.domMousewheel = function(e){
  317. var delta = e.detail;
  318. var step = ((this.options.distance.toFloat())/100)*(clientSize.y.toFloat());
  319. delta = (delta/6)*step;
  320. this.scroll(delta, null);
  321. e.stopPropagation();
  322. }.bind(this);
  323. this.touchmove = function(e){
  324. var delta = e.event.detail;
  325. var step = ((this.options.distance.toFloat())/100)*(clientSize.y.toFloat());
  326. delta = (delta/(clientSize.y.toFloat()))*step;
  327. this.scroll(delta, null);
  328. e.preventDefault();
  329. e.stopPropagation();
  330. }.bind(this);
  331. if (scrollSize.y>clientSize.y){
  332. if (!this.scrollVNode){
  333. // this.scrollVAreaNode = new Element("div", {
  334. // "styles": this.css.scrollVAreaNode
  335. // }).inject(this.node, "before");
  336. this.scrollVAreaNode = new Element("div", {
  337. "styles": this.css.scrollVAreaNode
  338. }).inject(this.node, this.options.where);
  339. //if (this.scrollVAreaNode.getStyle("position")=="absolute"){
  340. // this.scrollVAreaNode.position({
  341. // relativeTo: this.node,
  342. // position: "topright",
  343. // edge: "topleft"
  344. // });
  345. //}
  346. this.scrollVNode = new Element("div", {
  347. "styles": this.css.scrollVNode
  348. }).inject(this.scrollVAreaNode);
  349. var margin = this.node.getStyle("margin-right").toFloat();
  350. var marginTop = this.node.getStyle("margin-top").toFloat();
  351. var marginBottom = this.node.getStyle("margin-bottom").toFloat();
  352. var scrollVNodeSize = this.scrollVAreaNode.getSize();
  353. // this.node.tween("margin-right", margin+scrollVNodeSize.x);
  354. if (this.options.indent) this.scrollVAreaNode.setStyle("margin-right", margin);
  355. this.scrollVAreaNode.setStyle("margin-top", marginTop);
  356. this.scrollVAreaNode.setStyle("display", "none");
  357. this.scrollVWidth = this.scrollVAreaNode.getStyle("width").toFloat();
  358. this.setScrollVNodeMove();
  359. this.node.addEvent("mousewheel", this.mousewheel);
  360. this.node.addEvent("touchmove", this.touchmove);
  361. if (Browser.name=="firefox"){
  362. this.node.addEventListener("DOMMouseScroll", this.domMousewheel, false);
  363. }
  364. // this.node DOMMouseScroll
  365. }
  366. if (this.scrollVAreaNode.getStyle("position")=="absolute"){
  367. this.scrollVAreaNode.position({
  368. relativeTo: this.node,
  369. position: "topright",
  370. edge: "topleft"
  371. });
  372. }
  373. this.scrollVAreaNode.setStyle("height", clientSize.y);
  374. // this.setScrollNodePosition();
  375. }else{
  376. if (this.scrollVNode){
  377. if (!this.scrollAreaOutLock && !this.scrollAreaOverLock){
  378. if (!this.showScrollBar){
  379. this.scrollAreaOutLock = true;
  380. var scrollFx = new Fx.Tween(this.scrollVAreaNode, {property: "opacity", duration: "100"});
  381. scrollFx.start(0).chain(function(){
  382. var margin = this.node.getStyle("margin-right").toFloat();
  383. this.scrollVAreaNode.setStyle("display", "none");
  384. //var marginFx = new Fx.Tween(this.node, {property: "margin-right", duration: "100"});
  385. if (this.options.indent){
  386. var marginFx = new Fx.Tween(this.node, {property: "margin-right", duration: "100"});
  387. marginFx.start(margin-this.scrollVWidth).chain(function(){
  388. this.scrollAreaOutLock = false;
  389. this.scrollVAreaNode.destroy();
  390. this.scrollVNode = null;
  391. this.scrollVAreaNode = null;
  392. }.bind(this));
  393. }else{
  394. this.scrollAreaOutLock = false;
  395. this.scrollVAreaNode.destroy();
  396. this.scrollVNode = null;
  397. this.scrollVAreaNode = null;
  398. }
  399. }.bind(this));
  400. };
  401. };
  402. // var scrollVNodeSize = this.scrollVAreaNode.getSize();
  403. // var margin = this.node.getStyle("margin-right").toFloat();
  404. //
  405. // this.scrollVAreaNode.destroy();
  406. // this.scrollVNode = null;
  407. // this.scrollVAreaNode = null;
  408. // this.node.tween("margin-right", margin-scrollVNodeSize.x);
  409. }
  410. this.node.removeEvents("mousewheel", this.mousewheel);
  411. if (Browser.name=="firefox"){
  412. this.node.addEventListener("DOMMouseScroll", this.domMousewheel, false);
  413. }
  414. }
  415. // if (scrollSize.x>scrollSize.x){
  416. // alert("ddd");
  417. // var scrollNode = node.retrieve("scrollbarH");
  418. // if (!scrollNode){
  419. // var scrollNode = new Element("div", {
  420. // "styles": css
  421. // }).inject(node, "after");
  422. // alerrt("ddd");
  423. // var scrollNodeMove = new Drag.Move(scrollNode);
  424. // node.store("scrollbarH", scrollNode);
  425. // }
  426. // }
  427. }
  428. });