forked from scala/docs.scala-lang
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjquery.accordionza.js
271 lines (230 loc) · 7.99 KB
/
jquery.accordionza.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
/*
* Accordionza jQuery Plugin
* Copyright 2010, Geert De Deckere <geert@idoe.be>
*/
(function($) {
// Accordionza version
var version = '1.0.2';
$.fn.accordionza = function(options) {
// Merge all the options (recursively)
var o = $.extend(true, {}, $.fn.accordionza.defaults, options);
// Loop over each accordion
this.each(function() {
// Cache selector operations
var $accordion = $(this);
var $slides = $accordion.children('li');
var $firstSlide = $slides.filter(':first');
var $lastSlide = $slides.filter(':last');
var $activeSlide = $slides.filter('.' + o.classSlideOpened);
// Calculate widths and heights
var width = $accordion.width();
var height = $accordion.height();
var slideMinWidth = (o.slideWidthClosed === false) ? $slides.filter(':not(.' + o.classSlideOpened + '):first').find('.' + o.classHandle + ':first').outerWidth() : o.slideWidthClosed;
var slideMaxWidth = width - ($slides.length - 1) * slideMinWidth;
// Handlers for setInterval and setTimeout
var autoPlayInterval;
var autoPlayTimeout;
// Used for o.pauseOnHover functionality
var autoPlayPaused = false;
// Setup the accordion (wrapper)
$accordion.css({
'position': 'relative',
'overflow': 'hidden'
});
// Setup the slides
$slides.css({
'position': 'absolute',
'top': '0',
'width': slideMaxWidth + 'px',
'height': height + 'px'
});
// Position each slide
$slides.each(function(i) {
// We also store the order for each slide (starting with zero)
// This will come in handy later
$(this).css('left', i * slideMinWidth + 'px').data('order', i);
});
// Hide the captions
$('.' + o.classCaption, $slides).css('top', height + 'px');
// Start autoplaying
function startAutoPlay() {
// Make sure we don't start a double interval
stopAutoPlay();
autoPlayInterval = setInterval(function() {
// If not temporarily paused, trigger the next slide
if ( ! autoPlayPaused) {
nextSlide().trigger('slide');
}
}, o.slideDelay);
}
// Stop autoplaying
function stopAutoPlay() {
clearInterval(autoPlayInterval);
}
// Pause autoplaying for a while
function pauseAutoPlay(delay) {
// Set the default delay value
if (delay === undefined) {
var delay = o.autoRestartDelay;
}
stopAutoPlay();
// If the delay has been set to false (or 0),
// we won't restart autoplaying the slides.
if (delay === false) {
return;
}
// Clear any possible previous calls to this function
clearTimeout(autoPlayTimeout);
// Note: on top of the delay value below, you have to add the default o.slideDelay time
// to get the actual time the next slide gets triggered. This is because setInterval() in
// startAutoPlay() waits one delay iteration before starting.
autoPlayTimeout = setTimeout(function() {
startAutoPlay();
}, delay);
}
// Returns the previous slide
function prevSlide(loop) {
if (loop === undefined) {
var loop = true;
}
var $prevSlide = $activeSlide.prev();
if ($prevSlide.length) {
return $prevSlide;
} else if (loop) {
return $lastSlide;
} else {
return $activeSlide;
}
}
// Returns the next slide
function nextSlide(loop) {
if (loop === undefined) {
var loop = true;
}
var $nextSlide = $activeSlide.next();
if ($nextSlide.length) {
return $nextSlide;
} else if (loop) {
return $firstSlide;
} else {
return $activeSlide;
}
}
// Some slide was activated by the user
$slides.bind(o.slideTrigger, function() {
pauseAutoPlay();
$(this).trigger('slide');
});
// Some slide was activated
$slides.bind('slide', function() {
// Ignore clicks on an already opened slide
if ($(this).hasClass(o.classSlideOpened)) {
return;
}
// Switch the classSlideOpened
$activeSlide.removeClass(o.classSlideOpened);
$(this).addClass(o.classSlideOpened);
// Move all following slides to the right, and all preceding slides to the left
$slides.filter(':gt(' + $(this).data('order') + ')').each(function() {
$(this).stop(true).animate({left: slideMaxWidth + ($(this).data('order') - 1) * slideMinWidth + 'px'}, o.slideSpeed, o.slideEasing);
}).end().filter(':lt(' + ($(this).data('order') + 1) + ')').each(function() {
$(this).stop(true).animate({left: $(this).data('order') * slideMinWidth + 'px'}, o.slideSpeed, o.slideEasing);
});
// Hide the old caption, show the new one
$('.' + o.classCaption, $activeSlide).stop(true).animate({top: height + 'px'}, o.captionSpeed, o.captionEasing);
// Note: using delay() here from jQuery 1.4 instead of the "animate({opacity:0},delay)" trick from http://www.learningjquery.com/2007/01/effect-delay-trick
// Using opacity here would cause PNG transparency to break in IE
$('.' + o.classCaption, $(this)).stop(true).delay(o.captionDelay).animate({top: height - o.captionHeight + 'px'}, o.captionSpeed, o.captionEasing);
// User-defined callbacks
if ($.isFunction(o.onSlideClose)) {
o.onSlideClose.call($activeSlide);
}
if ($.isFunction(o.onSlideOpen)) {
o.onSlideOpen.call($(this));
}
// Custom event hook
$.event.trigger('accordionza_slide');
// Voilà, we've got a new open slide
$activeSlide = $(this);
});
// Animate and toggle the caption
$slides.find('.' + o.classCaptionToggle).click(function() {
pauseAutoPlay();
// Find the caption this classCaptionToggle instance belongs to
// Note: we don't assume classCaptionToggle is an ancestor of the caption
var $caption = $(this).closest('li').find('.' + o.classCaption);
if ( ! $activeSlide.hasClass(o.classCaptionCollapsed)) {
// Move the caption down
$caption.stop(true).animate({top: height - o.captionHeightClosed + 'px'}, o.captionSpeed, o.captionEasing);
} else {
// Move the caption back up
$caption.stop(true).animate({top: height - o.captionHeight + 'px'}, o.captionSpeed, o.captionEasing);
}
$activeSlide.toggleClass(o.classCaptionCollapsed);
});
// Keyboard navigation
if (o.navKey) {
$(document.documentElement).keyup(function(event) {
// Left arrow key
if (event.which == 37) {
prevSlide().trigger(o.slideTrigger);
// Right arrow key
} else if (event.which == 39) {
nextSlide().trigger(o.slideTrigger);
}
});
}
// Open up the start slide.
// Note: this code needs to come after the 'slide' binding to $slides.
if ($activeSlide.length) {
// If a slide with the classSlideOpened exists,
// we trigger the previous one so the correct slide opens up.
prevSlide().trigger('slide');
} else {
// If no slide with the classSlideOpened is found,
// we open up the first slide.
$lastSlide.addClass(o.classSlideOpened);
$activeSlide = $lastSlide;
$firstSlide.trigger('slide');
}
// Start autoplaying
if (o.autoPlay) {
// Temporarily pause the slideshow on hover
if (o.pauseOnHover) {
$accordion.mouseenter(function() {
autoPlayPaused = true;
}).mouseleave(function() {
autoPlayPaused = false;
});
}
startAutoPlay();
}
});
// Make chainable
return this;
};
// The complete list of default options
$.fn.accordionza.defaults = {
autoPlay: false,
autoRestartDelay: false,
captionDelay: 0,
captionEasing: 'swing',
captionHeight: 50,
captionHeightClosed: 0,
captionSpeed: 500,
classSlideOpened: 'slide_opened',
classCaption: 'slide_caption',
classCaptionCollapsed: 'slide_caption_collapsed',
classCaptionToggle: 'slide_caption_toggle',
classHandle: 'slide_handle',
navKey: false,
onSlideClose: null,
onSlideOpen: null,
pauseOnHover: false,
slideDelay: 5000,
slideEasing: 'swing',
slideSpeed: 500,
slideTrigger: 'click',
slideWidthClosed: false
};
})(jQuery);