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