jquery.doubleScroll.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. * @name DoubleScroll
  3. * @desc displays scroll bar on top and on the bottom of the div
  4. * @requires jQuery
  5. *
  6. * @author Pawel Suwala - http://suwala.eu/
  7. * @author Antoine Vianey - http://www.astek.fr/
  8. * @version 0.5 (11-11-2015)
  9. *
  10. * Dual licensed under the MIT and GPL licenses:
  11. * http://www.opensource.org/licenses/mit-license.php
  12. * http://www.gnu.org/licenses/gpl.html
  13. *
  14. * Usage:
  15. * https://github.com/avianey/jqDoubleScroll
  16. */
  17. (function( $ ) {
  18. jQuery.fn.doubleScroll = function(userOptions) {
  19. // Default options
  20. var options = {
  21. contentElement: undefined, // Widest element, if not specified first child element will be used
  22. scrollCss: {
  23. 'overflow-x': 'auto',
  24. 'overflow-y': 'hidden'
  25. },
  26. contentCss: {
  27. 'overflow-x': 'auto',
  28. 'overflow-y': 'hidden'
  29. },
  30. onlyIfScroll: true, // top scrollbar is not shown if the bottom one is not present
  31. resetOnWindowResize: false, // recompute the top ScrollBar requirements when the window is resized
  32. timeToWaitForResize: 30 // wait for the last update event (usefull when browser fire resize event constantly during ressing)
  33. };
  34. $.extend(true, options, userOptions);
  35. // do not modify
  36. // internal stuff
  37. $.extend(options, {
  38. topScrollBarMarkup: '<div class="doubleScroll-scroll-wrapper" style="height: 20px;"><div class="doubleScroll-scroll" style="height: 20px;"></div></div>',
  39. topScrollBarWrapperSelector: '.doubleScroll-scroll-wrapper',
  40. topScrollBarInnerSelector: '.doubleScroll-scroll'
  41. });
  42. var _showScrollBar = function($self, options) {
  43. if (options.onlyIfScroll && $self.get(0).scrollWidth <= $self.width()) {
  44. // content doesn't scroll
  45. // remove any existing occurrence...
  46. $self.prev(options.topScrollBarWrapperSelector).remove();
  47. return;
  48. }
  49. // add div that will act as an upper scroll only if not already added to the DOM
  50. var $topScrollBar = $self.prev(options.topScrollBarWrapperSelector);
  51. if ($topScrollBar.length == 0) {
  52. // creating the scrollbar
  53. // added before in the DOM
  54. $topScrollBar = $(options.topScrollBarMarkup);
  55. $self.before($topScrollBar);
  56. // apply the css
  57. $topScrollBar.css(options.scrollCss);
  58. $self.css(options.contentCss);
  59. // bind upper scroll to bottom scroll
  60. $topScrollBar.bind('scroll.doubleScroll', function() {
  61. $self.scrollLeft($topScrollBar.scrollLeft());
  62. });
  63. // bind bottom scroll to upper scroll
  64. var selfScrollHandler = function() {
  65. $topScrollBar.scrollLeft($self.scrollLeft());
  66. };
  67. $self.bind('scroll.doubleScroll', selfScrollHandler);
  68. }
  69. // find the content element (should be the widest one)
  70. var $contentElement;
  71. if (options.contentElement !== undefined && $self.find(options.contentElement).length !== 0) {
  72. $contentElement = $self.find(options.contentElement);
  73. } else {
  74. $contentElement = $self.find('>:first-child');
  75. }
  76. // set the width of the wrappers
  77. $(options.topScrollBarInnerSelector, $topScrollBar).width($contentElement.outerWidth());
  78. $topScrollBar.width($self.width());
  79. $topScrollBar.scrollLeft($self.scrollLeft());
  80. }
  81. return this.each(function() {
  82. var $self = $(this);
  83. _showScrollBar($self, options);
  84. // bind the resize handler
  85. // do it once
  86. if (options.resetOnWindowResize) {
  87. var id;
  88. var handler = function(e) {
  89. _showScrollBar($self, options);
  90. };
  91. $(window).bind('resize.doubleScroll', function() {
  92. // adding/removing/replacing the scrollbar might resize the window
  93. // so the resizing flag will avoid the infinite loop here...
  94. clearTimeout(id);
  95. id = setTimeout(handler, options.timeToWaitForResize);
  96. });
  97. }
  98. });
  99. }
  100. }( jQuery ));