You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
414 lines
10 KiB
414 lines
10 KiB
/** |
|
* Plugin Name : Accordion.JS |
|
* Version : 2.1.1 |
|
* Author : ZeroWP Team |
|
* Author URL : http://zerowp.com/ |
|
* Plugin URL : http://accordionjs.zerowp.com/ |
|
* License : MIT |
|
*/ |
|
;(function ( $ ) { |
|
|
|
"use strict"; |
|
|
|
$.fn.accordionjs = function( options ) { |
|
|
|
// Select all accordions that match a CSS selector |
|
if (this.length > 1){ |
|
this.each(function() { |
|
$(this).accordionjs(options); |
|
}); |
|
return this; |
|
} |
|
|
|
// Current accordion instance |
|
var accordion = this; |
|
|
|
// Setup utility functions |
|
var util = { |
|
|
|
/** |
|
* Is integer |
|
* |
|
* Check if a value is a valid integer number |
|
* |
|
* @param {number} value |
|
* @return {bool} |
|
*/ |
|
isInteger: function(value) { |
|
return typeof value === 'number' && |
|
isFinite(value) && |
|
Math.floor(value) === value; |
|
}, |
|
|
|
//------------------------------------//--------------------------------------// |
|
|
|
/** |
|
* Is array |
|
* |
|
* Check if a value is a valid array. |
|
* |
|
* @param {Array} arg |
|
* @return {bool} |
|
*/ |
|
isArray: function(arg) { |
|
return Object.prototype.toString.call(arg) === '[object Array]'; |
|
}, |
|
|
|
//------------------------------------//--------------------------------------// |
|
|
|
/** |
|
* Is object |
|
* |
|
* Check if a value is a valid object. |
|
* |
|
* @param {Object} arg |
|
* @return {bool} |
|
*/ |
|
isObject: function isObject(arg) { |
|
return Object.prototype.toString.call(arg) === '[object Object]'; |
|
}, |
|
|
|
//------------------------------------//--------------------------------------// |
|
|
|
/** |
|
* Sections is open |
|
* |
|
* Check if a section from current accordion is open. |
|
* |
|
* @param {Object}(jQuery) section |
|
* @return {bool} |
|
*/ |
|
sectionIsOpen: function( section ){ |
|
return section.hasClass( 'acc_active' ); |
|
}, |
|
|
|
|
|
//------------------------------------//--------------------------------------// |
|
|
|
/** |
|
* Get hash |
|
* |
|
* Get hash substring without # or false if the window does not have one. |
|
* |
|
* @return {string|bool(false)} |
|
*/ |
|
getHash: function(){ |
|
if(window.location.hash) { |
|
return window.location.hash.substring(1); |
|
} |
|
|
|
return false; |
|
}, |
|
}; |
|
|
|
/* Setup options |
|
---------------------*/ |
|
var settings = $.extend({ |
|
// Allow self close. |
|
closeAble : false, |
|
|
|
// Close other sections. |
|
closeOther : true, |
|
|
|
// Animation Speed. |
|
slideSpeed : 150, |
|
|
|
// The section open on first init. A number from 1 to X or false. |
|
activeIndex : 1, |
|
|
|
// Callback when a section is open |
|
openSection: false, // function( section ){} |
|
|
|
// Callback before a section is open |
|
beforeOpenSection: false, // function( section ){} |
|
}, options ); |
|
|
|
// Assign to accordion options data-* attributes if they exists |
|
$.each(settings, function( option ) { |
|
var data_attr = option.replace(/([A-Z])/g, '-$1').toLowerCase().toString(), //`optionsName` becomes `option-name` |
|
new_val = accordion.data( data_attr ); |
|
|
|
if( new_val || false === new_val ){ |
|
settings[ option ] = new_val; |
|
} |
|
}); |
|
|
|
/* |
|
If the activeIndex is false then all sections are closed by default. |
|
If the closeOther is false then other section will not be closed when |
|
this is opened. That means, in both cases, sections should be able |
|
to be closed independently. |
|
*/ |
|
if( settings.activeIndex === false || settings.closeOther === false ){ |
|
settings.closeAble = true; |
|
} |
|
|
|
//------------------------------------//--------------------------------------// |
|
|
|
/** |
|
* "Constructor" |
|
* |
|
* @return void |
|
*/ |
|
var init = function() { |
|
accordion.create(); |
|
accordion.openOnClick(); |
|
|
|
$(window).on( 'load', function(){ |
|
accordion.openOnHash(); |
|
}); |
|
|
|
$(window).on( 'hashchange', function(){ |
|
accordion.openOnHash(); |
|
}); |
|
}; |
|
|
|
//------------------------------------//--------------------------------------// |
|
|
|
/** |
|
* Open section |
|
* |
|
* Open a single section. |
|
* |
|
* @param {Object}(jQuery) section The section to open |
|
* @param {number} speed |
|
* @return void |
|
*/ |
|
this.openSection = function(section, speed){ |
|
// Event before a section is opened |
|
$(document).trigger('accjs_before_open_section', [ |
|
section, |
|
]); |
|
|
|
// Callback before a section is opened |
|
if( typeof settings.beforeOpenSection === "function" ){ |
|
settings.beforeOpenSection.call(this, section); |
|
} |
|
|
|
// Setup the collapse speed |
|
speed = ( speed >= 0 ) ? speed : settings.slideSpeed; |
|
|
|
// Get the section content |
|
var section_content = section.children().eq(1); // .acc_content |
|
|
|
// Open the section |
|
section_content.slideDown( speed, function(){ |
|
// Event when a section is opened |
|
$(document).trigger('accjs_open_section', [ |
|
section, |
|
]); |
|
|
|
// Callback when a section is opened |
|
if( typeof settings.openSection === "function" ){ |
|
settings.openSection.call(this, section); |
|
} |
|
} ); |
|
|
|
// Make active |
|
section.addClass('acc_active'); |
|
}; |
|
|
|
//------------------------------------//--------------------------------------// |
|
|
|
/** |
|
* Close section |
|
* |
|
* Close a single section. |
|
* |
|
* @param {Object}(jQuery) section The section to close |
|
* @param {number} speed |
|
* @return void |
|
*/ |
|
this.closeSection = function(section, speed){ |
|
// Event before a section is closed |
|
$(document).trigger('accjs_before_close_section', [ |
|
section, |
|
]); |
|
|
|
// Callback before a section is closed |
|
if( typeof settings.beforeCloseSection === "function" ){ |
|
settings.beforeCloseSection.call(this, section); |
|
} |
|
|
|
// Setup the collapse speed |
|
speed = ( speed >= 0 ) ? speed : settings.slideSpeed; |
|
|
|
// Get the section content |
|
var section_content = section.children().eq(1); // .acc_content |
|
|
|
// Open the section |
|
section_content.slideUp( speed, function(){ |
|
// Event when a section is closed |
|
$(document).trigger('accjs_close_section', [ |
|
section, |
|
]); |
|
|
|
// Callback when a section is closed |
|
if( typeof settings.closeSection === "function" ){ |
|
settings.closeSection.call(this, section); |
|
} |
|
|
|
} ); |
|
|
|
// Make inactive |
|
section.removeClass('acc_active'); |
|
|
|
}; |
|
|
|
//------------------------------------//--------------------------------------// |
|
|
|
/** |
|
* Close other sections except this one |
|
* |
|
* @param {Object}(jQuery) section The section to exclude |
|
* @param {number} speed |
|
* @return void |
|
*/ |
|
this.closeOtherSections = function(section, speed){ |
|
var this_acc = section.closest('.accordionjs').children(); |
|
$(this_acc).each(function() { |
|
accordion.closeSection( $(this).not(section), speed ); |
|
}); |
|
}; |
|
|
|
//------------------------------------//--------------------------------------// |
|
|
|
/** |
|
* Create the accordion |
|
* |
|
* Create the accordion structure. Add the necessary CSS classes and other stuff. |
|
* |
|
* @return void |
|
*/ |
|
this.create = function() { |
|
|
|
//Add Main CSS Class |
|
accordion.addClass('accordionjs'); |
|
|
|
// Get all current accordion sections |
|
var accordion_sections = accordion.children(); |
|
|
|
//Add classes to accordion head and content for each section |
|
$.each( accordion_sections, function(index, elem){ |
|
accordion.createSingleSection( $(elem) ); |
|
}); |
|
|
|
// //Active index |
|
if( util.isArray( settings.activeIndex ) ){ |
|
var indexes = settings.activeIndex; |
|
for (var i = 0; i < indexes.length; i++) { |
|
accordion.openSection( accordion_sections.eq( indexes[i] - 1 ), 0 ); |
|
} |
|
} |
|
else if( settings.activeIndex > 1 ){ |
|
accordion.openSection( accordion_sections.eq( settings.activeIndex - 1 ), 0 ); |
|
} |
|
else if( false !== settings.activeIndex ){ |
|
accordion.openSection( accordion_sections.eq( 0 ), 0 ); |
|
} |
|
|
|
}; |
|
|
|
//------------------------------------//--------------------------------------// |
|
|
|
/** |
|
* Create a single section |
|
* |
|
* Create the structure of a single section by adding the necessary CSS classes. |
|
* |
|
* @param {string} section The section to create. jQuery object. |
|
* @return void |
|
*/ |
|
this.createSingleSection = function( section ) { |
|
var childs = section.children(); |
|
|
|
// Create sections if they were not created already |
|
section.addClass('acc_section'); |
|
|
|
// Add the necessary CSS classes |
|
$(childs[0]).addClass('acc_head'); |
|
$(childs[1]).addClass('acc_content'); |
|
|
|
// Collapse section content. |
|
// Only if it does not have `.acc_active` CSS class set by default. |
|
if( ! section.hasClass('acc_active') ) { |
|
section.children('.acc_content').hide(); |
|
} |
|
}; |
|
|
|
//------------------------------------//--------------------------------------// |
|
|
|
/** |
|
* Open on click |
|
* |
|
* Open a section when its header get a click. |
|
* |
|
* @return void |
|
*/ |
|
this.openOnClick = function() { |
|
|
|
accordion.on('click', '.acc_head', function( event ){ |
|
event.stopImmediatePropagation(); |
|
|
|
var section = $(this).closest('.acc_section'); |
|
if( util.sectionIsOpen( section ) ) { |
|
|
|
// If closeAble, then close this section but do not touch other. |
|
if( settings.closeAble ) { |
|
accordion.closeSection( section ); |
|
} |
|
|
|
// If the accordion contains only one section, act like a toggle. |
|
else if( accordion.children().length === 1 ) { |
|
accordion.closeSection( section ); |
|
} |
|
|
|
} |
|
|
|
// Section is closed |
|
else { |
|
// If closeOther, then close other sections when this is opened. |
|
if( settings.closeOther ) { |
|
accordion.closeOtherSections( section ); |
|
accordion.openSection( section ); |
|
} |
|
|
|
// Else open only this section and do not touch other sections. |
|
else { |
|
accordion.openSection( section ); |
|
} |
|
} |
|
|
|
}); |
|
|
|
}; |
|
|
|
//------------------------------------//--------------------------------------// |
|
|
|
/** |
|
* Open a section if a hash is present in URL and scroll to it. |
|
* |
|
* @return void |
|
*/ |
|
this.openOnHash = function() { |
|
if( util.getHash() ) { |
|
var section = $( '#' + util.getHash() ); |
|
if( section.hasClass('acc_section') ) { |
|
accordion.openSection( section ); |
|
if( settings.closeOther ) { |
|
accordion.closeOtherSections( section ); |
|
} |
|
$("html, body").animate({ |
|
scrollTop: parseInt( section.offset().top ) - 50, |
|
}, 150); |
|
} |
|
} |
|
}; |
|
|
|
//"Constructor" init |
|
init(); |
|
return this; |
|
|
|
}; |
|
|
|
}( jQuery ));
|
|
|