jQueryプラグインを理解するためのjQuery関数とjQueryインスタンス

jQueryでプラグイン開発をする場合、jQuery.fnへの拡張を行ってするのはもはやテンプレなのですが、なぜfnへの拡張なのかをメモって見た。

jQueryインスタンス?

よく使う以下はjQueryインスタンスです

1
2
3
// セレクターを指定してjQueryにラップされたDOMオブジェクトが返る
$('#page');

もうちょっと細かく見ていきましょう。

この2つの実行形式は同じで、どちらもjQuery関数を実行している

1
2
3
$('#page');

jQuery('#page');

jQuery関数の中身はというと以下

1
2
3
4
var jQuery = function( selector, context ) {
// こいつが実行されている
return new jQuery.fn.init( selector, context, rootjQuery );
}

いつも、$(‘#page’)とかで取得してたやつの正体はこのnew jQuery.fn.initだった。

このjQueryインスタンスにはよく目にするメソッドが定義されている。

つまり、jqueryインスタンス自体に何かしらの拡張を行うには、このjQuery.fnへの拡張が必要になってくる。


jQueryオブジェクトへの拡張

jQuery自体もオブジェクトなのでメソッドを追加できる。
ここではインスタンスとの違いを見ていただきたい。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// jQueryオブジェクトへの拡張したメソッドを定義
jQuery.output_message = function (msg) {
console.log(msg);
};

// jQueryオブジェクトを参照してメソッドを実行した結果
$.output_message("aaa");

> aaa

// jQueryインスタンスを参照してメソッドを実行した結果
$().output_message("aaa");

// インスタンス自体への拡張ではないのでエラーになる
> Uncaught TypeError: $(...).output_message is not a function
at <anonymous>:1:5

jQueryインスタンスへの拡張

こちらはpluginを作る時によく目にするやりかたで、jQuery.fnへの拡張を行う。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// jQueryインスタンスへの拡張を行ったメソッドを定義
jQuery.fn.output_message = function (msg) {
console.log(msg);
};

// jQueryオブジェクトを参照してメソッドを実行した結果
$.output_message("aaa");

// jQuery自体への拡張ではないのでエラーになる
> Uncaught TypeError: $.output_message is not a function
at <anonymous>:1:3

// jQueryインスタンスを参照してメソッドを実行した結果
$().output_message("aaa");

> aaa


jQueryプラグイン実装

上記を踏まえて、jQueryプラグインの実装例を見ていく。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 実行時にパラメーターを渡せる仕様になっていると便利
$.fn.hiddenItem = function (config) {
// デフォルトパラメーター
var defaults = {
speed: "slow"
};
var options = $.extend(defaults, config);

// thisはjQueryインスタンス
return this.click(function() {
// ここのthisはjQueryインスタンスではないので$(this)を実行してjQueryインスタンス化する必要がある
$(this).fadeOut(options.speed);
})
};

$("#header").hiddenItem({speed: "normal"})

プラグイン内メソッドの外部呼出し

DOM依存じゃないものや、プラグインのなかで使用しているメソッドを公開メソッドとして使いたいなどの場合は以下のような形で呼び出せる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var F = $.myPlugin = function () {
F.open.apply( this, arguments );
};
$.extend(F, {
// 公開用メソッド
testMethod: function () {
console.log("test");
}
});
$.fn.myPlugin = function (config) {
var defaults = {
message: "yes"
};
var options = $.extend(defaults, config);

return this.click(function() {
alert(options.message)
})
};

$.myPlugin.testMethod();

> test

まとめ

pluginの機能提供範囲を意識しながらつくるとよいのではという感じです。