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.
415 lines
10 KiB
415 lines
10 KiB
2 years ago
|
/**
|
||
|
* 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 ));
|