scroll.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. /*
  2. * 描 述:滚动条优化
  3. */
  4. (function ($, learun, window) {
  5. "use strict";
  6. var $move = null;
  7. var methods = {
  8. init: function ($this, callback) {
  9. var id = $this.attr('id');
  10. if (!id) {
  11. id = 'lr_' + learun.newGuid();
  12. $this.attr('id', id);
  13. }
  14. $this.addClass('lr-scroll-wrap');
  15. // 加载内容
  16. var $content = $this.children();
  17. var $scroll = $('<div class="lr-scroll-box" id="' + id + '_box"></div>');
  18. $this.append($scroll);
  19. $scroll.append($content);
  20. // 加载y滚动条
  21. var $vertical = $('<div class="lr-scroll-vertical" ><div class="lr-scroll-vertical-block" id="' + id + '_vertical"></div></div>')
  22. $this.append($vertical);
  23. // 加载x滚动条
  24. var $horizontal = $('<div class="lr-scroll-horizontal" ><div class="lr-scroll-horizontal-block" id="' + id + '_horizontal"></div></div>')
  25. $this.append($horizontal);
  26. // 添加一个移动板
  27. if ($move === null) {
  28. $move = $('<div style="-moz-user-select: none;-webkit-user-select: none;-ms-user-select: none;-khtml-user-select: none;user-select: none;display: none;position: fixed;top: 0;left: 0;width: 100%;height: 100%;z-index: 9999;cursor: pointer;" ></div>');
  29. $('body').append($move);
  30. }
  31. // 初始化数据
  32. var sh = $scroll.innerHeight();
  33. var sw = $scroll.innerWidth();
  34. var h = $this.height();
  35. var w = $this.width();
  36. var data = {
  37. id: id,
  38. sy: 0,
  39. sx: 0,
  40. sh: sh,
  41. sw: sw,
  42. h: h,
  43. w: w,
  44. yh: 0,
  45. xw: 0,
  46. callback: callback
  47. };
  48. $this[0].op = data;
  49. methods.update($this);
  50. methods.bindEvent($this, $scroll, $vertical, $horizontal);
  51. $scroll = null;
  52. $content = null;
  53. $vertical = null;
  54. $horizontal = null;
  55. $this = null;
  56. },
  57. bindEvent: function ($this, $scroll, $vertical, $horizontal) { // 绑定监听事件
  58. // div大小变化
  59. $this.resize(function () {
  60. var $this = $(this);
  61. var op = $this[0].op;
  62. var h = $this.height();
  63. var w = $this.width();
  64. if (h != op.h) {
  65. op.h = h;
  66. methods.updateY($this);
  67. }
  68. if (w != op.w) {
  69. op.w = w;
  70. methods.updateX($this);
  71. }
  72. $this = null;
  73. });
  74. $scroll.resize(function () {
  75. var $this = $(this);
  76. var $scrollWrap = $this.parent();
  77. var op = $scrollWrap[0].op;
  78. var sh = $this.innerHeight();
  79. var sw = $this.innerWidth();
  80. if (sh != op.sh) {
  81. op.sh = sh;
  82. methods.updateY($scrollWrap);
  83. }
  84. if (sw != op.sw) {
  85. op.sw = sw;
  86. methods.updateX($scrollWrap);
  87. }
  88. $this = null;
  89. $scrollWrap = null;
  90. });
  91. // 监听鼠标滚动
  92. $this.mousewheel(function (event, delta, deltaX, deltaY) {
  93. var $this = $(this);
  94. var op = $this[0].op;
  95. var d = delta * 32;
  96. if (op.sh > op.h) {
  97. op.oldsy = op.sy;
  98. op.sy = op.sy - d;
  99. methods.moveY($this, true);
  100. $this = null;
  101. return false;
  102. } else if (op.sw > op.w) {
  103. op.oldsx = op.sx;
  104. op.sx = op.sx - d;
  105. methods.moveX($this, true);
  106. $this = null;
  107. return false;
  108. }
  109. });
  110. // 监听鼠标移动
  111. $vertical.find('.lr-scroll-vertical-block').on('mousedown', function (e) {
  112. $move.show();
  113. var $this = $(this).parent().parent();
  114. var op = $this[0].op;
  115. op.isYMousedown = true;
  116. op.yMousedown = e.pageY;
  117. $this.addClass('lr-scroll-active');
  118. $this = null;
  119. });
  120. $horizontal.find('.lr-scroll-horizontal-block').on('mousedown', function (e) {
  121. $move.show();
  122. var $this = $(this).parent().parent();
  123. var op = $this[0].op;
  124. op.isXMousedown = true;
  125. op.xMousedown = e.pageX;
  126. $this.addClass('lr-scroll-active');
  127. $this = null;
  128. });
  129. top.$(document).on('mousemove', { $obj: $this }, function (e) {
  130. var op = e.data.$obj[0].op;
  131. if (op.isYMousedown) {
  132. var y = e.pageY;
  133. var _yd = y - op.yMousedown;
  134. op.yMousedown = y;
  135. op.oldsy = op.sy;
  136. op.blockY = op.blockY + _yd;
  137. if ((op.blockY + op.yh) > op.h) {
  138. op.blockY = op.h - op.yh;
  139. }
  140. if (op.blockY < 0) {
  141. op.blockY = 0;
  142. }
  143. methods.getY(op);
  144. methods.moveY(e.data.$obj);
  145. }
  146. else if (op.isXMousedown) {
  147. var op = e.data.$obj[0].op;
  148. var x = e.pageX;
  149. var _xd = x - op.xMousedown;
  150. op.xMousedown = x;
  151. op.oldsx = op.sx;
  152. op.blockX = op.blockX + _xd;
  153. if ((op.blockX + op.xw) > op.w) {
  154. op.blockX = op.w - op.xw;
  155. }
  156. if (op.blockX < 0) {
  157. op.blockX = 0;
  158. }
  159. methods.getX(op);
  160. methods.moveX(e.data.$obj);
  161. }
  162. }).on('mouseup', { $obj: $this }, function (e) {
  163. e.data.$obj[0].op.isYMousedown = false;
  164. e.data.$obj[0].op.isXMousedown = false;
  165. $move.hide();
  166. e.data.$obj.removeClass('lr-scroll-active');
  167. });
  168. },
  169. update: function ($this) { // 更新滚动条
  170. methods.updateY($this);
  171. methods.updateX($this);
  172. },
  173. updateY: function ($this) {
  174. var op = $this[0].op;
  175. var $scroll = $this.find('#' + op.id + '_box');
  176. var $vertical = $this.find('#' + op.id + '_vertical');
  177. if (op.sh > op.h) { // 出现纵向滚动条
  178. // 更新显示区域位置
  179. if ((op.sh - op.sy) < op.h) {
  180. var _sy = 0;
  181. op.sy = op.sh - op.h;
  182. if (op.sy < 0) {
  183. op.sy = 0;
  184. } else {
  185. _sy = 0 - op.sy;
  186. }
  187. $scroll.css('top', _sy + 'px');
  188. }
  189. // 更新滚动条高度
  190. var scrollH = parseInt(op.h * op.h / op.sh);
  191. scrollH = (scrollH < 30 ? 30 : scrollH);
  192. op.yh = scrollH;
  193. // 更新滚动条位置
  194. var _y = parseInt(op.sy * (op.h - scrollH) / (op.sh - op.h));
  195. if ((_y + scrollH) > op.h) {
  196. _y = op.h - scrollH;
  197. }
  198. if (_y < 0) {
  199. _y = 0;
  200. }
  201. op.blockY = _y;
  202. // 设置滚动块大小和位置
  203. $vertical.css({
  204. 'top': _y + 'px',
  205. 'height': scrollH + 'px'
  206. });
  207. } else {
  208. op.blockY = 0;
  209. op.sy = 0;
  210. $scroll.css('top', '0px');
  211. $vertical.css({
  212. 'top': '0px',
  213. 'height': '0px'
  214. });
  215. }
  216. op.callback && op.callback(op.sx, op.sy);
  217. $scroll = null;
  218. $vertical = null;
  219. },
  220. updateX: function ($this) {
  221. var op = $this[0].op;
  222. var $scroll = $this.find('#' + op.id + '_box');
  223. var $horizontal = $this.find('#' + op.id + '_horizontal');
  224. if (op.sw > op.w) {
  225. // 更新显示区域位置
  226. if ((op.sw - op.sx) < op.w) {
  227. var _sx = 0;
  228. op.sx = op.sw - op.w;
  229. if (op.sx < 0) {
  230. op.sx = 0;
  231. } else {
  232. _sx = 0 - op.sx;
  233. }
  234. $scroll.css('left', _sx + 'px');
  235. }
  236. // 更新滚动条高度
  237. var scrollW = parseInt(op.w * op.w / op.sw);
  238. scrollW = (scrollW < 30 ? 30 : scrollW);
  239. op.xw = scrollW;
  240. // 更新滚动条位置
  241. var _x = parseInt(op.sx * (op.w - scrollW) / (op.sw - op.w));
  242. if ((_x + scrollW) > op.w) {
  243. _x = op.w - scrollW;
  244. }
  245. if (_x < 0) {
  246. _x = 0;
  247. }
  248. op.blockX = _x;
  249. // 设置滚动块大小和位置
  250. $horizontal.css({
  251. 'left': _x + 'px',
  252. 'width': scrollW + 'px'
  253. });
  254. } else {
  255. op.sx = 0;
  256. op.blockX = 0;
  257. $scroll.css('left', '0px');
  258. $horizontal.css({
  259. 'left': '0px',
  260. 'width': '0px'
  261. });
  262. }
  263. op.callback && op.callback(op.sx, op.sy);
  264. $scroll = null;
  265. $horizontal = null;
  266. },
  267. moveY: function ($this, isMousewheel) {
  268. var op = $this[0].op;
  269. var $scroll = $this.find('#' + op.id + '_box');
  270. var $vertical = $this.find('#' + op.id + '_vertical');
  271. // 更新显示区域位置
  272. var _sy = 0;
  273. if (op.sy < 0) {
  274. op.sy = 0;
  275. } else if (op.sy + op.h > op.sh) {
  276. op.sy = op.sh - op.h;
  277. _sy = 0 - op.sy;
  278. } else {
  279. _sy = 0 - op.sy;
  280. }
  281. if (isMousewheel) {
  282. var _y = methods.getBlockY(op);
  283. if (_y == 0 && op.sy != 0) {
  284. op.sy = 0;
  285. _sy = 0;
  286. }
  287. op.blockY = _y;
  288. // 设置滚动块位置
  289. //var d = Math.abs(op.sy - op.oldsy) * 100 / 4;
  290. $scroll.css({
  291. 'top': _sy + 'px'
  292. });
  293. $vertical.css({
  294. 'top': _y + 'px'
  295. });
  296. } else {
  297. $scroll.css({
  298. 'top': _sy + 'px'
  299. });
  300. $vertical.css({
  301. 'top': op.blockY + 'px'
  302. });
  303. }
  304. op.callback && op.callback(op.sx, op.sy);
  305. $scroll = null;
  306. $vertical = null;
  307. },
  308. moveX: function ($this, isMousewheel) {
  309. var op = $this[0].op;
  310. var $scroll = $this.find('#' + op.id + '_box');
  311. var $horizontal = $this.find('#' + op.id + '_horizontal');
  312. // 更新显示区域位置
  313. var _sx = 0;
  314. if (op.sx < 0) {
  315. op.sx = 0;
  316. } else if (op.sx + op.w > op.sw) {
  317. op.sx = op.sw - op.w;
  318. _sx = 0 - op.sx;
  319. } else {
  320. _sx = 0 - op.sx;
  321. }
  322. if (isMousewheel) {
  323. // 更新滑块的位置
  324. var _x = methods.getBlockX(op);
  325. if (_x == 0 && op.sx != 0) {
  326. op.sx = 0;
  327. _sx = 0;
  328. }
  329. op.blockX = _x;
  330. // 设置滚动块位置
  331. //var d = Math.abs(op.sx - op.oldsx) * 100 / 4;
  332. $scroll.css({
  333. 'left': _sx + 'px'
  334. });
  335. $horizontal.css({
  336. 'left': _x + 'px'
  337. });
  338. } else {
  339. $scroll.css({
  340. 'left': _sx + 'px'
  341. });
  342. $horizontal.css({
  343. 'left': op.blockX + 'px'
  344. });
  345. }
  346. op.callback && op.callback(op.sx, op.sy);
  347. $scroll = null;
  348. $horizontal = null;
  349. },
  350. getBlockY: function (op) {
  351. var _y = parseFloat(op.sy * (op.h - op.yh) / (op.sh - op.h));
  352. if ((_y + op.yh) > op.h) {
  353. _y = op.h - op.yh;
  354. }
  355. if (_y < 0) {
  356. _y = 0;
  357. }
  358. return _y;
  359. },
  360. getY: function (op) {
  361. op.sy = parseInt(op.blockY * (op.sh - op.h) / (op.h - op.yh));
  362. if ((op.sy + op.h) > op.sh) {
  363. op.sy = op.sh - op.h;
  364. }
  365. if (op.sy < 0) {
  366. op.sy = 0;
  367. }
  368. },
  369. getBlockX: function (op) {
  370. var _x = parseFloat(op.sx * (op.w - op.xw) / (op.sw - op.w));
  371. if ((_x + op.xw) > op.w) {
  372. _x = op.w - op.xw;
  373. }
  374. if (_x < 0) {
  375. _x = 0;
  376. }
  377. return _x;
  378. },
  379. getX: function (op) {
  380. op.sx = parseInt(op.blockX * (op.sw - op.w) / (op.w - op.xw));
  381. if ((op.sx + op.w) > op.sw) {
  382. op.sx = op.sw - op.w;
  383. }
  384. if (op.sx < 0) {
  385. op.sx = 0;
  386. }
  387. },
  388. };
  389. $.fn.lrscroll = function (callback) {
  390. $(this).each(function () {
  391. var $this = $(this);
  392. methods.init($this, callback);
  393. });
  394. }
  395. $.fn.lrscrollSet = function (name, data) {
  396. switch (name) {
  397. case 'moveRight':
  398. var $this = $(this);
  399. setTimeout(function () {
  400. var op = $this[0].op;
  401. op.oldsx = op.sx;
  402. op.sx = op.sw - op.w;
  403. methods.moveX($this, true);
  404. $this = null;
  405. }, 250);
  406. break;
  407. case 'moveBottom':
  408. var $this = $(this);
  409. setTimeout(function () {
  410. var op = $this[0].op;
  411. op.oldsy = op.sx;
  412. op.sy = op.sh - op.h;
  413. methods.moveY($this, true);
  414. $this = null;
  415. }, 250);
  416. break;
  417. }
  418. }
  419. })(window.jQuery, top.learun, window);