jQueryを使ってタブメニュープラグインを作る

前回はjQueryを使ってタブメニューのインターフェイスを作成しましたが、汎用的に利用するにはプラグイン化すると便利です。プラグイン化するとプラグインを呼び出す際のオプションを設定出来るので、liやdivのクラス名を変更した際にも対応出来ます。

今回は前回のコードを参考にプラグイン化して行きます。

前回のjQueryコードは次のようなコードになります。

jQuery Code

$(function(){
	var box = $('.tab-box');	   
	var tabList = $('.tab-list').find('li');
	box.not(':first').hide();
	tabList.eq(0).addClass('selected');
	tabList.click(function(){
		var tabIndex = tabList.index(this);
		tabList.removeClass('selected');
		$(this).addClass('selected');
		box.hide().eq(tabIndex).addClass('selected').fadeIn();
	});
});

今回のコードの完成形です。

jQuery Plugin Code

(function($) {
	$.fn.tabs = function(options) {
		var o = $.extend({
			targetID: '#tab',
			tabElement: '.tab-list li',
			boxElement: '.tab-box'
		}, options);
		$(o.tabElement, o.targetID).each(function() {
			$(o.boxElement, o.targetID).not(':first').hide();
			$(o.tabElement, o.targetID).eq(0).addClass('selected');
			$(this).click(function() {
				var tabIndex = $(o.tabElement, o.targetID).index(this);
				$(o.tabElement, o.targetID).removeClass('selected');
				$(this).addClass('selected');
				$(o.boxElement, o.targetID).hide().eq(tabIndex).addClass('selected').fadeIn();
			});
		});
		return this;
	};
})(jQuery);

それでは解説して行きましょう。プラグイン化するにはjQueryオブジェクトに対して新しいメソッドとして定義する必要があります。メソッドを定義するには$.fn.メソッド名と書きます。

(function($) {
	$.fn.tabs = function() {
		});
		return this;
	};
})(jQuery);

次にこのプラグインのオプションとする内容を考えます。
今回は1ページで複数のタブを使う事を考慮して特定のIDを付加したdivに包まれたタブを1つのタブグループとして利用出来るようにします。例えば1個目のタブはdiv#tabs1、2個目のタブはdiv#tabs2のような使い方が出来るようにします。また、ulに指定するクラス名、表示・非表示するdivに指定するクラス名も指定出来るようにします。

箇条書きにすると次のようになります。

  • 1ページ内で複数のタブとして利用出来るようにdiv#ID名をフックにする。
  • タブのulに付加するクラス名、表示・非表示するdivのクラス名を環境によって変更出来るように。

このようなオプションを設定するには引数を設定してメソッド内で利用出来るようにします。

(function($) {
	$.fn.tabs = function(options) {
		var o = $.extend({
		}, options);
		});
		return this;
	};
})(jQuery);

$.extend({...},options);で作成するメソッドにオプションが設定出来るようになります。オプションの内容は{...}に記述します。$.extendに関してはてっく煮ブログ jQuery.extend マニアックスに詳しい記事として掲載されていますので参考にしてみて下さい。

(function($) {
	$.fn.tabs = function(options) {
		var o = $.extend({
			targetID: '#tab',
			tabElement: '.tab-list li',
			boxElement: '.tab-box'
		}, options);
		return this;
	};
})(jQuery);

設定するオプションはtargetIDでタブのIDを、tabElementでクリックするタブのulに付加するクラス名を、boxElementで表示・非表示するdivに付加するクラス名にします。それぞれに初期値を設定します。

これでこのメソッドを呼び出す時にオプションに設定した値を変更出来ます。呼び出す場合は次のように記述します。

$(function() {
	$.fn.tabs({
		targetID: '#tabs1',
		tabElement: '.tabs li',
		boxelement: '.section'
	});
});

次のステップは振る舞いです。設定したtargetID(#tab)のtabElement(.tab-list li)がクリックされた時の振る舞いを記述して行きます。

(function($) {
	$.fn.tabs = function(options) {
		var o = $.extend({
			targetID: '#tab',
			tabElement: '.tab-list li',
			boxElement: '.tab-box'
		}, options);
		$(o.tabElement, o.targetID).each(function() {
		});
		return this;
	};
})(jQuery);

設定したオプションはo.targetIDの様な形で呼び出す事が出来ます。o.targetIDのo.tabElementに合致した全ての要素に対してメソッドを実効させるにはeach()を使います。
$(o.tabElement, o.targetID)と記述する事により、o.targetIDのコンテキストに含まれるo.tabElement(要は#tab .tab-list liと同様)に対してメソッドが実効されていきます。

each()内でまず最初にやることは前回と同様に画面が表示された時の初期設定を行います。前回のコードの『box.not(':first').hide(); tabList.eq(0).addClass('selected');』の部分です。

(function($) {
	$.fn.tabs = function(options) {
		var o = $.extend({
			targetID: '#tab',
			tabElement: '.tab-list li',
			boxElement: '.tab-box'
		}, options);
		$(o.tabElement, o.targetID).each(function() {
			$(o.boxElement, o.targetID).not(':first').hide();
			$(o.tabElement, o.targetID).eq(0).addClass('selected');
		});
		return this;
	};
})(jQuery);

boxが$(o.boxElement, o.targetID)、tabListが(o.tabElement, o.targetID)に変わっただけで前回と同じ記述です。タブがクリックされた時の挙動に進みましょう。基本的には前回の記述と変わりませんが、クリックされる要素を指定するには$(this)を使います。

(function($) {
	$.fn.tabs = function(options) {
		var o = $.extend({
			targetID: '#tab',
			tabElement: '.tab-list li',
			boxElement: '.tab-box'
		}, options);
		$(o.tabElement, o.targetID).each(function() {
			$(o.boxElement, o.targetID).not(':first').hide();
			$(o.tabElement, o.targetID).eq(0).addClass('selected');
			$(this).click(function() {
				var tabIndex = $(o.tabElement, o.targetID).index(this);
				$(o.tabElement, o.targetID).removeClass('selected');
				$(this).addClass('selected');
				$(o.boxElement, o.targetID).hide().eq(tabIndex).addClass('selected').fadeIn();
			});
		});
		return this;
	};
})(jQuery);

ここで注意しておくのは$(this).click(function() {});のthisと.index(this)のthisは違うと言う事です。外側のthisはクリックされる前のo.tabElement, o.targetIDであり、内側のthisはクリックされたo.tabElement, o.targetIDです。ややっこしいですが、jQuery内ではthisが何を指すかと言う事がとても大事になります。

これでプラグインの完成です。外部ファイル(例:jquery.tabs.js)にこのコードを書き、HTML側のsrc属性で読み込みます。そして先ほど書いた呼び出すコードでこのメソッドを呼び出せば良いわけです。

View Demo

2回に渡って出来る限りわかりやすくを心がけて記事にしましたが、不十分な点、もっとこう書くべきだと言う事もあるかと思います。その点はご了承下さい。また、この2回のエントリーがきっかけでjQueryを少し勉強してみようと思っていただければ幸いです。