Skip to content

Instantly share code, notes, and snippets.

@kodie
Created July 28, 2023 15:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kodie/51298e728a34a5c80defce1cd8bc0f7d to your computer and use it in GitHub Desktop.
Save kodie/51298e728a34a5c80defce1cd8bc0f7d to your computer and use it in GitHub Desktop.
A accordion jQuery plugin - Originally created by the good people over at PSD2HTML.com - Simply here so we can pull the code in remotely
/*
* jQuery Open/Close plugin
*/
;(function($) {
function OpenClose(options) {
this.options = $.extend({
addClassBeforeAnimation: true,
hideOnClickOutside: false,
activeClass: 'active',
opener: '.opener',
slider: '.slide',
animSpeed: 400,
effect: 'fade',
event: 'click'
}, options);
this.init();
}
OpenClose.prototype = {
init: function() {
if (this.options.holder) {
this.findElements();
this.attachEvents();
this.makeCallback('onInit', this);
}
},
findElements: function() {
this.holder = $(this.options.holder);
this.opener = this.holder.find(this.options.opener);
this.slider = this.holder.find(this.options.slider);
},
attachEvents: function() {
// add handler
var self = this;
this.eventHandler = function(e) {
e.preventDefault();
if (self.slider.hasClass(slideHiddenClass)) {
self.showSlide();
} else {
self.hideSlide();
}
};
self.opener.on(self.options.event, this.eventHandler);
// hover mode handler
if (self.options.event === 'hover') {
self.opener.on('mouseenter', function() {
if (!self.holder.hasClass(self.options.activeClass)) {
self.showSlide();
}
});
self.holder.on('mouseleave', function() {
self.hideSlide();
});
}
// outside click handler
self.outsideClickHandler = function(e) {
if (self.options.hideOnClickOutside) {
var target = $(e.target);
if (!target.is(self.holder) && !target.closest(self.holder).length) {
self.hideSlide();
}
}
};
// set initial styles
if (this.holder.hasClass(this.options.activeClass)) {
$(document).on('click touchstart', self.outsideClickHandler);
} else {
this.slider.addClass(slideHiddenClass);
}
},
showSlide: function() {
var self = this;
if (self.options.addClassBeforeAnimation) {
self.holder.addClass(self.options.activeClass);
}
self.slider.removeClass(slideHiddenClass);
$(document).on('click touchstart', self.outsideClickHandler);
self.makeCallback('animStart', true);
toggleEffects[self.options.effect].show({
box: self.slider,
speed: self.options.animSpeed,
complete: function() {
if (!self.options.addClassBeforeAnimation) {
self.holder.addClass(self.options.activeClass);
}
self.makeCallback('animEnd', true);
}
});
},
hideSlide: function() {
var self = this;
if (self.options.addClassBeforeAnimation) {
self.holder.removeClass(self.options.activeClass);
}
$(document).off('click touchstart', self.outsideClickHandler);
self.makeCallback('animStart', false);
toggleEffects[self.options.effect].hide({
box: self.slider,
speed: self.options.animSpeed,
complete: function() {
if (!self.options.addClassBeforeAnimation) {
self.holder.removeClass(self.options.activeClass);
}
self.slider.addClass(slideHiddenClass);
self.makeCallback('animEnd', false);
}
});
},
destroy: function() {
this.slider.removeClass(slideHiddenClass).css({
display: ''
});
this.opener.off(this.options.event, this.eventHandler);
this.holder.removeClass(this.options.activeClass).removeData('OpenClose');
$(document).off('click touchstart', this.outsideClickHandler);
},
makeCallback: function(name) {
if (typeof this.options[name] === 'function') {
var args = Array.prototype.slice.call(arguments);
args.shift();
this.options[name].apply(this, args);
}
}
};
// add stylesheet for slide on DOMReady
var slideHiddenClass = 'js-slide-hidden';
(function() {
var tabStyleSheet = $('<style type="text/css">')[0];
var tabStyleRule = '.' + slideHiddenClass;
tabStyleRule += '{position:absolute !important;left:-9999px !important;top:-9999px !important;display:block !important}';
if (tabStyleSheet.styleSheet) {
tabStyleSheet.styleSheet.cssText = tabStyleRule;
} else {
tabStyleSheet.appendChild(document.createTextNode(tabStyleRule));
}
$('head').append(tabStyleSheet);
}());
// animation effects
var toggleEffects = {
slide: {
show: function(o) {
o.box.stop(true).hide().slideDown(o.speed, o.complete);
},
hide: function(o) {
o.box.stop(true).slideUp(o.speed, o.complete);
}
},
fade: {
show: function(o) {
o.box.stop(true).hide().fadeIn(o.speed, o.complete);
},
hide: function(o) {
o.box.stop(true).fadeOut(o.speed, o.complete);
}
},
none: {
show: function(o) {
o.box.hide().show(0, o.complete);
},
hide: function(o) {
o.box.hide(0, o.complete);
}
}
};
// jQuery plugin interface
$.fn.openClose = function(opt) {
var args = Array.prototype.slice.call(arguments);
var method = args[0];
return this.each(function() {
var $holder = jQuery(this);
var instance = $holder.data('OpenClose');
if (typeof opt === 'object' || typeof opt === 'undefined') {
$holder.data('OpenClose', new OpenClose($.extend({
holder: this
}, opt)));
} else if (typeof method === 'string' && instance) {
if (typeof instance[method] === 'function') {
args.shift();
instance[method].apply(instance, args);
}
}
});
};
}(jQuery));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment