| 2 |
lars |
1 |
/**
|
|
|
2 |
* Plugin Name : Accordion.JS
|
|
|
3 |
* Version : 2.1.0
|
|
|
4 |
* Author : ZeroWP Team
|
|
|
5 |
* Author URL : http://zerowp.com/
|
|
|
6 |
* Plugin URL : http://accordionjs.zerowp.com/
|
|
|
7 |
* License : MIT
|
|
|
8 |
*/
|
|
|
9 |
;(function ( $ ) {
|
|
|
10 |
|
|
|
11 |
"use strict";
|
|
|
12 |
|
|
|
13 |
$.fn.accordionjs = function( options ) {
|
|
|
14 |
|
|
|
15 |
// Select all accordions that match a CSS selector
|
|
|
16 |
if (this.length > 1){
|
|
|
17 |
this.each(function() {
|
|
|
18 |
$(this).accordionjs(options);
|
|
|
19 |
});
|
|
|
20 |
return this;
|
|
|
21 |
}
|
|
|
22 |
|
|
|
23 |
// Current accordion instance
|
|
|
24 |
var accordion = this;
|
|
|
25 |
|
|
|
26 |
// Setup utility functions
|
|
|
27 |
var util = {
|
|
|
28 |
|
|
|
29 |
/**
|
|
|
30 |
* Is integer
|
|
|
31 |
*
|
|
|
32 |
* Check if a value is a valid integer number
|
|
|
33 |
*
|
|
|
34 |
* @param {number} value
|
|
|
35 |
* @return {bool}
|
|
|
36 |
*/
|
|
|
37 |
isInteger: function(value) {
|
|
|
38 |
return typeof value === 'number' &&
|
|
|
39 |
isFinite(value) &&
|
|
|
40 |
Math.floor(value) === value;
|
|
|
41 |
},
|
|
|
42 |
|
|
|
43 |
//------------------------------------//--------------------------------------//
|
|
|
44 |
|
|
|
45 |
/**
|
|
|
46 |
* Is array
|
|
|
47 |
*
|
|
|
48 |
* Check if a value is a valid array.
|
|
|
49 |
*
|
|
|
50 |
* @param {Array} arg
|
|
|
51 |
* @return {bool}
|
|
|
52 |
*/
|
|
|
53 |
isArray: function(arg) {
|
|
|
54 |
return Object.prototype.toString.call(arg) === '[object Array]';
|
|
|
55 |
},
|
|
|
56 |
|
|
|
57 |
//------------------------------------//--------------------------------------//
|
|
|
58 |
|
|
|
59 |
/**
|
|
|
60 |
* Is object
|
|
|
61 |
*
|
|
|
62 |
* Check if a value is a valid object.
|
|
|
63 |
*
|
|
|
64 |
* @param {Object} arg
|
|
|
65 |
* @return {bool}
|
|
|
66 |
*/
|
|
|
67 |
isObject: function isObject(arg) {
|
|
|
68 |
return Object.prototype.toString.call(arg) === '[object Object]';
|
|
|
69 |
},
|
|
|
70 |
|
|
|
71 |
//------------------------------------//--------------------------------------//
|
|
|
72 |
|
|
|
73 |
/**
|
|
|
74 |
* Sections is open
|
|
|
75 |
*
|
|
|
76 |
* Check if a section from current accordion is open.
|
|
|
77 |
*
|
|
|
78 |
* @param {Object}(jQuery) section
|
|
|
79 |
* @return {bool}
|
|
|
80 |
*/
|
|
|
81 |
sectionIsOpen: function( section ){
|
|
|
82 |
return section.hasClass( 'acc_active' );
|
|
|
83 |
},
|
|
|
84 |
|
|
|
85 |
|
|
|
86 |
//------------------------------------//--------------------------------------//
|
|
|
87 |
|
|
|
88 |
/**
|
|
|
89 |
* Get hash
|
|
|
90 |
*
|
|
|
91 |
* Get hash substring without # or false if the window does not have one.
|
|
|
92 |
*
|
|
|
93 |
* @return {string|bool(false)}
|
|
|
94 |
*/
|
|
|
95 |
getHash: function(){
|
|
|
96 |
if(window.location.hash) {
|
|
|
97 |
return window.location.hash.substring(1);
|
|
|
98 |
}
|
|
|
99 |
|
|
|
100 |
return false;
|
|
|
101 |
},
|
|
|
102 |
};
|
|
|
103 |
|
|
|
104 |
/* Setup options
|
|
|
105 |
---------------------*/
|
|
|
106 |
var settings = $.extend({
|
|
|
107 |
// Allow self close.
|
|
|
108 |
closeAble : false,
|
|
|
109 |
|
|
|
110 |
// Close other sections.
|
|
|
111 |
closeOther : true,
|
|
|
112 |
|
|
|
113 |
// Animation Speed.
|
|
|
114 |
slideSpeed : 150,
|
|
|
115 |
|
|
|
116 |
// The section open on first init. A number from 1 to X or false.
|
|
|
117 |
activeIndex : 1,
|
|
|
118 |
|
|
|
119 |
// Callback when a section is open
|
|
|
120 |
openSection: false, // function( section ){}
|
|
|
121 |
|
|
|
122 |
// Callback before a section is open
|
|
|
123 |
beforeOpenSection: false, // function( section ){}
|
|
|
124 |
}, options );
|
|
|
125 |
|
|
|
126 |
// Assign to accordion options data-* attributes if they exists
|
|
|
127 |
$.each(settings, function( option ) {
|
|
|
128 |
var data_attr = option.replace(/([A-Z])/g, '-$1').toLowerCase().toString(), //`optionsName` becomes `option-name`
|
|
|
129 |
new_val = accordion.data( data_attr );
|
|
|
130 |
|
|
|
131 |
if( new_val || false === new_val ){
|
|
|
132 |
settings[ option ] = new_val;
|
|
|
133 |
}
|
|
|
134 |
});
|
|
|
135 |
|
|
|
136 |
/*
|
|
|
137 |
If the activeIndex is false then all sections are closed by default.
|
|
|
138 |
If the closeOther is false then other section will not be closed when
|
|
|
139 |
this is opened. That means, in both cases, sections should be able
|
|
|
140 |
to be closed independently.
|
|
|
141 |
*/
|
|
|
142 |
if( settings.activeIndex === false || settings.closeOther === false ){
|
|
|
143 |
settings.closeAble = true;
|
|
|
144 |
}
|
|
|
145 |
|
|
|
146 |
//------------------------------------//--------------------------------------//
|
|
|
147 |
|
|
|
148 |
/**
|
|
|
149 |
* "Constructor"
|
|
|
150 |
*
|
|
|
151 |
* @return void
|
|
|
152 |
*/
|
|
|
153 |
var init = function() {
|
|
|
154 |
accordion.create();
|
|
|
155 |
accordion.openOnClick();
|
|
|
156 |
|
|
|
157 |
$(window).on( 'load', function(){
|
|
|
158 |
accordion.openOnHash();
|
|
|
159 |
});
|
|
|
160 |
|
|
|
161 |
$(window).on( 'hashchange', function(){
|
|
|
162 |
accordion.openOnHash();
|
|
|
163 |
});
|
|
|
164 |
};
|
|
|
165 |
|
|
|
166 |
//------------------------------------//--------------------------------------//
|
|
|
167 |
|
|
|
168 |
/**
|
|
|
169 |
* Open section
|
|
|
170 |
*
|
|
|
171 |
* Open a single section.
|
|
|
172 |
*
|
|
|
173 |
* @param {Object}(jQuery) section The section to open
|
|
|
174 |
* @param {number} speed
|
|
|
175 |
* @return void
|
|
|
176 |
*/
|
|
|
177 |
this.openSection = function(section, speed){
|
|
|
178 |
// Event before a section is opened
|
|
|
179 |
$(document).trigger('accjs_before_open_section', [
|
|
|
180 |
section,
|
|
|
181 |
]);
|
|
|
182 |
|
|
|
183 |
// Callback before a section is opened
|
|
|
184 |
if( typeof settings.beforeOpenSection === "function" ){
|
|
|
185 |
settings.beforeOpenSection.call(this, section);
|
|
|
186 |
}
|
|
|
187 |
|
|
|
188 |
// Setup the collapse speed
|
|
|
189 |
speed = ( speed >= 0 ) ? speed : settings.slideSpeed;
|
|
|
190 |
|
|
|
191 |
// Get the section content
|
|
|
192 |
var section_content = section.children().eq(1); // .acc_content
|
|
|
193 |
|
|
|
194 |
// Open the section
|
|
|
195 |
section_content.slideDown( speed, function(){
|
|
|
196 |
// Event when a section is opened
|
|
|
197 |
$(document).trigger('accjs_open_section', [
|
|
|
198 |
section,
|
|
|
199 |
]);
|
|
|
200 |
|
|
|
201 |
// Callback when a section is opened
|
|
|
202 |
if( typeof settings.openSection === "function" ){
|
|
|
203 |
settings.openSection.call(this, section);
|
|
|
204 |
}
|
|
|
205 |
} );
|
|
|
206 |
|
|
|
207 |
// Make active
|
|
|
208 |
section.addClass('acc_active');
|
|
|
209 |
};
|
|
|
210 |
|
|
|
211 |
//------------------------------------//--------------------------------------//
|
|
|
212 |
|
|
|
213 |
/**
|
|
|
214 |
* Close section
|
|
|
215 |
*
|
|
|
216 |
* Close a single section.
|
|
|
217 |
*
|
|
|
218 |
* @param {Object}(jQuery) section The section to close
|
|
|
219 |
* @param {number} speed
|
|
|
220 |
* @return void
|
|
|
221 |
*/
|
|
|
222 |
this.closeSection = function(section, speed){
|
|
|
223 |
// Event before a section is closed
|
|
|
224 |
$(document).trigger('accjs_before_close_section', [
|
|
|
225 |
section,
|
|
|
226 |
]);
|
|
|
227 |
|
|
|
228 |
// Callback before a section is closed
|
|
|
229 |
if( typeof settings.beforeCloseSection === "function" ){
|
|
|
230 |
settings.beforeCloseSection.call(this, section);
|
|
|
231 |
}
|
|
|
232 |
|
|
|
233 |
// Setup the collapse speed
|
|
|
234 |
speed = ( speed >= 0 ) ? speed : settings.slideSpeed;
|
|
|
235 |
|
|
|
236 |
// Get the section content
|
|
|
237 |
var section_content = section.children().eq(1); // .acc_content
|
|
|
238 |
|
|
|
239 |
// Open the section
|
|
|
240 |
section_content.slideUp( speed, function(){
|
|
|
241 |
// Event when a section is closed
|
|
|
242 |
$(document).trigger('accjs_close_section', [
|
|
|
243 |
section,
|
|
|
244 |
]);
|
|
|
245 |
|
|
|
246 |
// Callback when a section is closed
|
|
|
247 |
if( typeof settings.closeSection === "function" ){
|
|
|
248 |
settings.closeSection.call(this, section);
|
|
|
249 |
}
|
|
|
250 |
|
|
|
251 |
} );
|
|
|
252 |
|
|
|
253 |
// Make inactive
|
|
|
254 |
section.removeClass('acc_active');
|
|
|
255 |
|
|
|
256 |
};
|
|
|
257 |
|
|
|
258 |
//------------------------------------//--------------------------------------//
|
|
|
259 |
|
|
|
260 |
/**
|
|
|
261 |
* Close other sections except this one
|
|
|
262 |
*
|
|
|
263 |
* @param {Object}(jQuery) section The section to exclude
|
|
|
264 |
* @param {number} speed
|
|
|
265 |
* @return void
|
|
|
266 |
*/
|
|
|
267 |
this.closeOtherSections = function(section, speed){
|
|
|
268 |
var this_acc = section.closest('.accordionjs').children();
|
|
|
269 |
$(this_acc).each(function() {
|
|
|
270 |
accordion.closeSection( $(this).not(section), speed );
|
|
|
271 |
});
|
|
|
272 |
};
|
|
|
273 |
|
|
|
274 |
//------------------------------------//--------------------------------------//
|
|
|
275 |
|
|
|
276 |
/**
|
|
|
277 |
* Create the accordion
|
|
|
278 |
*
|
|
|
279 |
* Create the accordion structure. Add the necessary CSS classes and other stuff.
|
|
|
280 |
*
|
|
|
281 |
* @return void
|
|
|
282 |
*/
|
|
|
283 |
this.create = function() {
|
|
|
284 |
|
|
|
285 |
//Add Main CSS Class
|
|
|
286 |
accordion.addClass('accordionjs');
|
|
|
287 |
|
|
|
288 |
// Get all current accordion sections
|
|
|
289 |
var accordion_sections = accordion.children();
|
|
|
290 |
|
|
|
291 |
//Add classes to accordion head and content for each section
|
|
|
292 |
$.each( accordion_sections, function(index, elem){
|
|
|
293 |
accordion.createSingleSection( $(elem) );
|
|
|
294 |
});
|
|
|
295 |
|
|
|
296 |
// //Active index
|
|
|
297 |
if( util.isArray( settings.activeIndex ) ){
|
|
|
298 |
var indexes = settings.activeIndex;
|
|
|
299 |
for (var i = 0; i < indexes.length; i++) {
|
|
|
300 |
accordion.openSection( accordion_sections.eq( indexes[i] - 1 ), 0 );
|
|
|
301 |
}
|
|
|
302 |
}
|
|
|
303 |
else if( settings.activeIndex > 1 ){
|
|
|
304 |
accordion.openSection( accordion_sections.eq( settings.activeIndex - 1 ), 0 );
|
|
|
305 |
}
|
|
|
306 |
else if( false !== settings.activeIndex ){
|
|
|
307 |
accordion.openSection( accordion_sections.eq( 0 ), 0 );
|
|
|
308 |
}
|
|
|
309 |
|
|
|
310 |
};
|
|
|
311 |
|
|
|
312 |
//------------------------------------//--------------------------------------//
|
|
|
313 |
|
|
|
314 |
/**
|
|
|
315 |
* Create a single section
|
|
|
316 |
*
|
|
|
317 |
* Create the structure of a single section by adding the necessary CSS classes.
|
|
|
318 |
*
|
|
|
319 |
* @param {string} section The section to create. jQuery object.
|
|
|
320 |
* @return void
|
|
|
321 |
*/
|
|
|
322 |
this.createSingleSection = function( section ) {
|
|
|
323 |
var childs = section.children();
|
|
|
324 |
|
|
|
325 |
// Create sections if they were not created already
|
|
|
326 |
section.addClass('acc_section');
|
|
|
327 |
|
|
|
328 |
// Add the necessary CSS classes
|
|
|
329 |
$(childs[0]).addClass('acc_head');
|
|
|
330 |
$(childs[1]).addClass('acc_content');
|
|
|
331 |
|
|
|
332 |
// Collapse section content.
|
|
|
333 |
// Only if it does not have `.acc_active` CSS class set by default.
|
|
|
334 |
if( ! section.hasClass('acc_active') ) {
|
|
|
335 |
section.children('.acc_content').hide();
|
|
|
336 |
}
|
|
|
337 |
};
|
|
|
338 |
|
|
|
339 |
//------------------------------------//--------------------------------------//
|
|
|
340 |
|
|
|
341 |
/**
|
|
|
342 |
* Open on click
|
|
|
343 |
*
|
|
|
344 |
* Open a section when its header get a click.
|
|
|
345 |
*
|
|
|
346 |
* @return void
|
|
|
347 |
*/
|
|
|
348 |
this.openOnClick = function() {
|
|
|
349 |
|
|
|
350 |
accordion.on('click', '.acc_head', function( event ){
|
|
|
351 |
event.stopImmediatePropagation();
|
|
|
352 |
|
|
|
353 |
var section = $(this).closest('.acc_section');
|
|
|
354 |
if( util.sectionIsOpen( section ) ) {
|
|
|
355 |
|
|
|
356 |
// If closeAble, then close this section but do not touch other.
|
|
|
357 |
if( settings.closeAble ) {
|
|
|
358 |
accordion.closeSection( section );
|
|
|
359 |
}
|
|
|
360 |
|
|
|
361 |
// If the accordion contains only one section, act like a toggle.
|
|
|
362 |
else if( accordion.children().length === 1 ) {
|
|
|
363 |
accordion.closeSection( section );
|
|
|
364 |
}
|
|
|
365 |
|
|
|
366 |
}
|
|
|
367 |
|
|
|
368 |
// Section is closed
|
|
|
369 |
else {
|
|
|
370 |
// If closeOther, then close other sections when this is opened.
|
|
|
371 |
if( settings.closeOther ) {
|
|
|
372 |
accordion.closeOtherSections( section );
|
|
|
373 |
accordion.openSection( section );
|
|
|
374 |
}
|
|
|
375 |
|
|
|
376 |
// Else open only this section and do not touch other sections.
|
|
|
377 |
else {
|
|
|
378 |
accordion.openSection( section );
|
|
|
379 |
}
|
|
|
380 |
}
|
|
|
381 |
|
|
|
382 |
});
|
|
|
383 |
|
|
|
384 |
};
|
|
|
385 |
|
|
|
386 |
//------------------------------------//--------------------------------------//
|
|
|
387 |
|
|
|
388 |
/**
|
|
|
389 |
* Open a section if a hash is present in URL and scroll to it.
|
|
|
390 |
*
|
|
|
391 |
* @return void
|
|
|
392 |
*/
|
|
|
393 |
this.openOnHash = function() {
|
|
|
394 |
if( util.getHash() ) {
|
|
|
395 |
var section = $( '#' + util.getHash() );
|
|
|
396 |
if( section.hasClass('acc_section') ) {
|
|
|
397 |
accordion.openSection( section );
|
|
|
398 |
if( settings.closeOther ) {
|
|
|
399 |
accordion.closeOtherSections( section );
|
|
|
400 |
}
|
|
|
401 |
$("html, body").animate({
|
|
|
402 |
scrollTop: parseInt( section.offset().top ) - 50,
|
|
|
403 |
}, 150);
|
|
|
404 |
}
|
|
|
405 |
}
|
|
|
406 |
};
|
|
|
407 |
|
|
|
408 |
//"Constructor" init
|
|
|
409 |
init();
|
|
|
410 |
return this;
|
|
|
411 |
|
|
|
412 |
};
|
|
|
413 |
|
|
|
414 |
}( jQuery ));
|