jQueryプラグインのメソッドパターン

このエントリーはjQuery Advent Calendar 2013の 最終目のエントリーです。(Advent Calendarとは様々なテーマを12/1〜12/25までリレー形式でブログなどに執筆する企画です。)

今回はjQueryプラグインのメソッドパターンについて紹介をしたいと思います。

jQueryプラグインのメソッドとはどいうものかというと、まず以下のようなプラグインがあったとします。

$.fn.alert = function(options){
	return this.each(function(){
		$(this).click(function(){
			alert(options.text);
			return false;
		})
	});
}

セレクタで指定した要素でアラートを表示するだけの簡単なプラグインです。(プラグインの作り方は「とりあえずjQueryのプラグイン作ってみる | Web | position: absolute;」を参考に)

プラグインの実行は以下のように行ないます。

$(".target").alert({
	text:"ok!!!"
});

サンプル

ただ、実行した後にもうこの処理が必要なくなった場合はどうすればよいでしょうか?

次のように直接イベントのunbindをやってしまえばよいのですが、これはプラグインがなにをしているか、どこにイベントを指定されているかを理解していないとできません。

$(".target").off("click");

今回のように数行のプラグインの場合はプラグインを読めばいいですが、何千行とかになってくるとちょっと厳しいですね。

そこであらかじめプラグインに破棄のメソッドを組み込んでおき、破棄のメソッドが実行された際にプラグインで仕込んだイベントやCSS、HTMLを取り除く際などに利用します。

よく利用されるメソッドパターンとしては以下の2つがあります。

Widget Factoryパターン

jQuery UIが提供するWidget Factoryを利用してメソッドを指定する方法です。

Widget Factoryではプラグインの実装が先程のプラグインとは異なるので、先程のプラグインをWidget Factoryを利用して書きなおしてみましょう。jQuery UIを読み込んでおけば以下のように書くことができます。

$.widget("my.alert", {
	_create: function(){
		var _this = this;
		this.element.click(function(){
			alert(_this.options.text);
			return false;
		});
	}
});

実行方法は先程のプラグインと一緒です。

$(".target").alert({
	text:"ok!!!"
});

サンプル

このように独自のプラグイン実装機構をもったのがjQuery UIのWidget Factoryです。

では、これにalertを破棄するdestoryメソッドを追加します。

$.widget("my.alert", {
	_create: function(){
		var _this = this;
		this.element.click(function(){
			alert(_this.options.text);
			return false;
		});
	},
	destory: function(){
		this.element.off("click");
	}
});

widgetの設定時にメソッドを追加するだけで簡単に追加できます。次のように実行すると.destoryがクリックされた際にdestoryメソッドが実行され、alertで指定した処理が破棄されます。

$(".destory").click(function(){
	$(".target").alert("destory");
	return false;
});

サンプル

jQuery Boilerplateパターン

Widget Factoryパターンと同様に有名なものにjQuery Boilerplateパターンがあり、jQuery プラグインの雛形を提供するjQuery Boilerplateで採用されているメソッドの指定方法です。

jQuery Boilerplateを利用して先程のプラグインを書きなおしてみます。長いですがinit: function () {...}内以外は雛形をそのまま利用しています。

;(function ( $, window, document, undefined ) {
	var pluginName = "alert",
		defaults = {};
	function Plugin ( element, options ) {
			this.element = element;
			this.settings = $.extend( {}, defaults, options );
			this._defaults = defaults;
			this._name = pluginName;
			this.init();
	}
	Plugin.prototype = {
		init: function () {
			var _this=this;
			$(this.element).click(function(){
				alert(_this.settings.text);
				return false;
			});
		}
	};
	$.fn[ pluginName ] = function ( options ) {
		return this.each(function() {
			if ( !$.data( this, "plugin_" + pluginName ) ) {
				$.data( this, "plugin_" + pluginName, new Plugin( this, options ) );
			}
		});
	};
})( jQuery, window, document );

実行方法はこれまでのプラグインと一緒です。

$(".target").alert({
	text:"ok!!!"
});

サンプル

では、これにalertを破棄するdestoryメソッドを追加します。

;(function ( $, window, document, undefined ) {
	var pluginName = "alert",
		defaults = {};
	function Plugin ( element, options ) {
			this.element = element;
			this.settings = $.extend( {}, defaults, options );
			this._defaults = defaults;
			this._name = pluginName;
			this.init();
	}
	Plugin.prototype = {
		init: function () {
			var _this=this;
			$(this.element).click(function(){
				alert(_this.settings.text);
				return false;
			});
		},
		destory: function(){
			$(this.element).off("click");
		}
	};
	$.fn[ pluginName ] = function ( options ) {
		return this.each(function() {
			if ( !$.data( this, "plugin_" + pluginName ) ) {
				$.data( this, "plugin_" + pluginName, new Plugin( this, options ) );
			}
		});
	};
})( jQuery, window, document );

こちらもWidget Factoryパターンと同じくdestoryメソッドを追加するだけ。ただ、呼び出し方法が若干異なり次のようにdataメソッドを実行してからdestoryメソッドを実行します。

$(".destory").click(function(){
	$(".target").data("plugin_alert").destory();
	return false;
});

サンプル

オレオレメソッドパターン

個人的にはWidget FactoryパターンはjQuery UIが必要でカジュアルに使いにくいのでちょっといやだし、jQuery Boilerplateパターンもdata()で呼び出すのが気持ちわるいのでちょっといやだということで以下のように利用するのが多いです。

$.fn.alert = function(options){
	if(options === "destory"){
		this.trigger("destory");
		return this;
	}
	return this.each(function(){
		$(this).on("click.alert",function(){
			alert(options.text);
			return false;
		}).on("destory.alert",function(){
			$(this).off("click.alert destory.alert")
		});
	});
}

実行方法はこれまでのプラグインと一緒です。

$(".target").alert({
	text:"ok!!!"
});

destoryメソッドの実行方法はWidget Factoryパターンと同じです。

$(".destory").click(function(){
	$(".target").alert("destory");
	return false;
});

サンプル

他にも色々とパターンがありますが、有名所のメソッドパターンとわたしが普段使っている方法を紹介してみました。

関連エントリー

jQuery基礎文法最速マスター
jQueryを良くする25のTIPS
14のjQueryベストプラクティス
8のjQueryのすごいTIPS
Re:初心者のコーダーでも簡単に実装出来るJavaScript/jQuery Tips

スポンサードリンク

«【Code match】クリエイターのための就業プログラムのご案内 | メイン | jQuery Advent Calendar 2013まとめ»