とってもシンプルなプラグインを作ります。ただ、どういう仕組みで動いているかというのを事細かに記載しているサイトは少ないので、そのあたりにこだわって、自分なりの理解を丁寧に解説してみます。
プラグインの完成イメージは、こんな感じです。
Labelタグに対して、プラグインのメソッドを呼び出すと、タイマーで指定した間隔でLabelのTextがカウントアップされていきます。実際に呼び出している部分のHTMLとJavaScriptをご紹介します。
HTML
[html]
[/html]
JavaScript
[js]
$(“#counter1”).simpleTimer();
[/js]
これだけです。
では、プラグイン本体のソースを以下に紹介します。
[js]
(function($){
$.fn.simpleTimer = function(options){
var target = this;
var defaults = {
interval : 1000,
timerFunc: null
};
var settings = $.extend(defaults, options);;
var elementFunc = function(elem){
//init
var cnt = 0;
var init = function (){
setInterval(function(){
$(elem).text(cnt);
cnt++;
if (settings.timerFunc != null){
settings.timerFunc(elem, cnt, settings.interval);
}
}
,settings.interval);
$(elem).click(function(){
cnt = 0;
});
};
init();
};
var ret = $(this).each(function(){
elementFunc(this);
});
return ret;
}
})(jQuery);
[/js]
一見難しそうに見えるので、分割して説明します。
プラグイン名の決定と、プラグインを作る上での決まり
まず、
[js]
(function($){
})(jQuery);
[/js]
で囲みます。
これで、プラグイン内と外部スクリプトの干渉を抑えます。
もう少し具体的に言うと、(function($)) という関数に 引数 jQueryを渡して、実行しているという意味になります。
つまり、引数$ には jQueryというオブジェクトが飛んできていて、この関数内で $ と書くと (jQuery)と書いているのと同義になります。
[js]
$.fn.simpleTimer = function(options){};
[/js]
これで jQueryに simpleTimerというメソッドを追加しますという意味になります。??ちょいとわかりにくいですね。上で説明したように $は (jQuery)を意味しており、 $.fn はjQueryのメソッド定義空間となっています(jQueryの仕様でそうなってます)。その定義空間に「simpleTimer」を追加します というのが $.fn.simpleTimer の部分です。で、そのsimpleTimerというのの実態は 引数 optionsをとる functionですよ、と定義していることになります。
例えば、 Labelタグ ID=”aaa”をクリックしたというのを定義する場合は
[js]
$(“#aaa”).click(function(){xxxxxx;});
[/js]
と記載しますよね。
これは $.fn.click というのが $.fnというメソッド定義空間に 存在しているという意味です。
jQueryのソースの中身をチェックしたわけではありませんが、クリックイベントは以下のように定義されているのでしょう。
[js]
jQuery.fn.click = function(){};
[/js]
今回は clickの代わりに自分で作るプラグイン名「simpleTimer」というメソッドを定義したという意味になります。これで何ができるようになったかというと、JavaScriptで jQueryでエレメント指定して、ドットでつないで、simpleTimerメソッドを呼び出せるようになったということです。文字で書くと難しいですが、要は以下のような記述が可能になったということです。
[js]
$(“#aaa”).simpleTimer();
[/js]
ここまで、ご理解いただけましたか? じゃぁ次に行ってみましょう。
プラグインの実行と戻り値(メソッドチェーンを可能にする)
[js]
(function($){
$.fn.simpleTimer = function(options){
var elementFunc = function(elem,options){
};
var ret = $(this).each(function(){
elementFunc(this);
});
return ret;
};
})(jQuery);
[/js]
なんだか小難しいですね。simpleTimerというメソッドを プラグインを使う人が
[js]
$(“#aaa”).simpleTimer();
[/js]
と呼びだすと、何らかの処理を実行して、戻り値を戻しているということになります。そして、 $(this).each(function(){elementFunc(this);});
という部分。
まず、jQueryプラグインにおいて、this には、指定された DOMエレメントが入ってくるという決まりになっています。
つまり、今回の例でいうと thisは ID = “aaa” というDOMエレメントということになります。
$(this)とは、 ID = “aaa” に対応する jQueryオブジェクトということになります。そのオブジェクトに対して、jQueryのeachメソッドを呼び出していると。一般的にはID指定すると1つのDOMエレメントとなりますが、ID = “aaa”のエレメントが複数ある場合、$(this)は、複数のエレメントを指しているということになります。その複数のエレメントに対して、jQueryのeachメソッドを呼んでいるという意味ですね。で、何を実行するかというと、プラグイン本体メソッド elementFuncを呼び出しているということになります。ここで注意していただきたいのが、
ここの thisは ID = “aaa” のDOMエレメント(複数のエレメントになるケースあり)
[js]
var ret = $(this).each(function(){
[/js]
ここのthisは、 ID = “aaa” のDOMエレメント(個別のエレメント!!)
[js]
elementFunc(this);
[/js]
という違いがあるということです。
要は、jQuery(セレクター).simpleTimer() で指定されたセレクターに当てはまる DOMエレメント1つ1つに対して、elementFuncを実行するよ!という意味になります。
そして、
[js]
var ret = $(this).each()
return ret;
[/js]
jQueryのeachメソッドは 引数に与えられたfunctionを実行します。が、戻り値は、実行するfunctionの内容にかかわらず、jQueryセレクターとなります。つまり今回の場合は戻り値が、 $(this)になるということです。こうすることでどんなメリットがあるかというと、プラグインを利用する人がメソッドチェーンを利用できるということになります。
もっと具体的にいうと、こんな記述が可能になりますよ!ということです。
[js]
$(“#aaa”).simpleTimer().click(function(){xxxxx;});
[/js]
プラグインの機能(実行する処理)
では、プラグインのメインルーチン elementFuncについて、解説しておきます。
[js]
var elementFunc = function(elem){
//init
var cnt = 0;
var init = function (){
setInterval(function(){
$(elem).text(cnt);
cnt++;
if (settings.timerFunc != null){
settings.timerFunc(elem, cnt, settings.interval);
}
}
,settings.interval);
$(elem).click(function(){
cnt = 0;
});
};
init();
};
[/js]
これは、何も複雑に考える必要もない、シンプルな JavaScriptの関数です。引数はelemです。
- 関数の先頭で cntという数値型の変数を宣言し、0で初期化します。
- 次に 内部関数 init を呼び出します。
- init関数は setIntervalでタイマー処理を実行します。タイマーの実行間隔は、 settings.intervalです。実行する中身は、引数で与えられた DOMエレメントのTextに変数 cntをセットするという、至ってシンプルな作りです。そしてTextの値を変更した後に cnt変数をカウントアップします。そして settings.timerFuncという変数がnullでなければ、settings.timerFuncを実行する。最後にもし elemがクリックされたら、cntを0に戻すという処理が記述されています。
プラグインのオプション引数
さて、関数の内部で settingsと出てきましたが、これは何者でしょうか?これは、simpleTimerメソッドを呼び出すときに指定したオプション引数の中身となります。具体的なソースでいうと以下の部分になります。
[js]
$.fn.simpleTimer = function(options){
var target = this;
var defaults = {
interval : 1000,
timerFunc: null
};
var settings = $.extend(defaults, options);;
[/js]
optionsには、プラグイン呼び出し時に以下のように引数を与えることができます。
[js]
$(“#aaa”).simpleTimer({aaa:”hello”,bbb:”goodbye”});
[/js]
プラグイン内部では、渡された引数と、デフォルト値を、jQueryの機能 $.extendでマージし、その結果を settingsというプラグイン内部で利用可能な変数にセットしています。
今回のプラグインでは、タイマーの処理間隔の初期値を1000(つまり1秒)、タイマー実行時に呼び出すfunctionをnull(つまり何も呼び出さない)が初期値となっています。
もし、実行間隔を伸ばしたいという場合は、呼び出す際に以下のような記述をすることが可能です。
[js]
$(“#aaa”).simpleTimer({interval: 5000});
[/js]
これで5秒毎にタイマーが実行されることになります。加えて、タイマー処理時に独自の処理を実行したいという場合には、以下のような記述で対応可能となります。
[js]
$(“#aaa”).simpleTimer({timerFunc: function(elem,count,interval){
//何らかの処理
var msg = “Debug from user script”;
msg += “ElementId = ” + elem.id;
msg += ” count = ” + count;
msg += ” /interval info = ” + interval;
console.log(msg);
});
[/js]
完成イメージ確認
では、再度完成イメージのビデオを見て、どんな感じで処理が行われているか確認してみてください。
プラグインを利用するHTMLとJavaScriptのソースです。
ビデオで確認すると、タイマーが実行されて、カウントアップが始まり、Labelをクリックすると、クリックされたLabelのみ、カウンターが初期化されているのが確認できると思います。また、 #counter1には、タイマー実行時に呼び出すメソッドを定義し、メソッド内でコンソール出力を行っているので、ご自身のスクリプト実行環境でコンソールログも確認してみてください。
[html]
[/html]
[js]
$(function(){
$(“#counter1”).simpleTimer({interval:1000,timerFunc:function(elem, count,interval){
var msg = “Debug from user script”;
msg += “ElementId = ” + elem.id;
msg += ” count = ” + count;
msg += ” /interval info = ” + interval;
console.log(msg);
}
}).click(function(){
$(this).text(“clicked”);
});
$(“label.hogehoge”).simpleTimer().click(function(){
$(this).text(“hogehoge clicked”);
});
});
[/js]
以上となります。
プラグインにはいろんな記述方法があるみたいですが、自分のお気に入りで理解しやすい方法を1つマスターすればOKだと思います。今回の例はその1パターンになります。良ければ参考にしてみてください。
Leave a comment