/* customAccordion.js $("トリガーのセレクタ").customAccordion({ toggleContent: xxxxx, //トグルするコンテンツのjQueryオブジェクト、またはそれを返すfunction 引数:options duration: "fast", //animate()のduraiton (デフォルト: "fast") easing: "linear", //animate()のeasing (デフォルト: "linear") triggerClass: { //トリガーに付加するクラス (デフォルト: { opened: "close", closeed: "open" }) opened: "open", //開いている状態のとき付加するクラス closed: "close" //閉じている状態のときに付加するクラス }, toggleTriggerTxt: { //トリガーのテキストを切り替える場合 (オプショナル) opened: "閉じる", //開いている状態のテキスト closed: "開く" //閉じている状態のテキスト }, beforeOpen: null, //開き始めの処理 endOpen: null, //開き終わりの処理 beforeClose: null, //閉じ始めの処理 endClose: null //閉じ終わりの処理 }); toggleContentをfunctionで指定した場合、thisはトリガーのエレメントとなる 例:トリガーの直後のdivをトグルするコンテンツとする場合 toggleContent: function(options) { return $(this).next("div"); } toggleContentにdisplay: noneが指定されているとデフォルトで閉じた状態、 そうでなければデフォルトで開いた状態になる 各コールバックのthisもトリガーエレメントとなる */ (function($) { $.fn.customAccordion = function(options) { if(!this || this.size() == 0) return; options = $.extend({}, $.customAccordionDefault, options); var toggleContent = options.toggleContent; var duration = options.duration; var easing = options.easing; var tiriggerClass = options.triggerClass; var toggleTriggerTxt = options.toggleTriggerTxt; var beforeOpen = options.beforeOpen; var endOpen = options.endOpen; var beforeClose = options.beforeClose; var endClose = options.endClose; //toggleClass用に連結 var triggerClassTxt = tiriggerClass.opened + " " + tiriggerClass.closed; return this.each(function(index) { //切り替えるクラスをひとまず外す var $trigger = $(this).removeClass(triggerClassTxt) //toggleContentがFunctionであれば実行してjQueryオブジェクトを取得(そうでなければそのまま) var $toggleContent = $.isFunction(toggleContent)? toggleContent.apply($trigger, [options]): toggleContent; //コンテンツの状態によって初期化 if($toggleContent.css("display") == "none") { $trigger.addClass(tiriggerClass.closed); if(toggleTriggerTxt) $trigger.text(toggleTriggerTxt.closed); //if($.isFunction(beforeClose)) beforeClose.apply($trigger, [options]); } else { $trigger.addClass(tiriggerClass.opened); if(toggleTriggerTxt) $trigger.text(toggleTriggerTxt.opened); //if($.isFunction(beforeOpen)) beforeOpen.apply($trigger, [options]); } //クリックアクション $trigger.click(function(e) { //トリガーのクラス切り替え var isOpened = $trigger.hasClass(tiriggerClass.opened); if(!isOpened) { if($.isFunction(beforeOpen)) beforeOpen.apply($trigger, [options]); } else { if($.isFunction(beforeClose)) beforeClose.apply($trigger, [options]); } $trigger.toggleClass(triggerClassTxt); isOpened = !isOpened; if(toggleTriggerTxt) { //トリガーのテキスト切り替え $trigger.html(toggleTriggerTxt[isOpened? "opened": "closed"]); } //コンテンツの切り替え var contentsDataHeight = $toggleContent.data("height"); var animatePropertyHeight = contentsDataHeight? (isOpened? contentsDataHeight: 0): "toggle"; if(duration > 0) { $toggleContent.animate({ height: animatePropertyHeight }, duration, easing, function() { if(isOpened) { if($.isFunction(endOpen)) endOpen.apply($trigger, [options]); } else { $toggleContent.hide(); if($.isFunction(endClose)) endClose.apply($trigger, [options]); } }); } else { if(isOpened) { $toggleContent.show(); if($.isFunction(endClose)) endClose.apply($trigger, [options]); } else { $toggleContent.hide(); if($.isFunction(endOpen)) endOpen.apply($trigger, [options]); } } e.preventDefault(); return false; }); }); } //デフォルトオプション $.customAccordionDefault = { duration: "fast", easing: "linear", triggerClass: { opened: "open", closed: "close" }, toggleTriggerTxt: null, beforeOpen: null, endOpen: null, beforeClose: null, endClose: null } })(jQuery);