jQueryプラグインの
作り方について詳しく

jhc_jqplugin

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

アジェンダ

  1. そもそものはなし
  2. jQueryプラグインってなに?
  3. jQueryプラグインにオプションを渡す
  4. jQueryプラグインに静的(static)関数を追加する
  5. jQueryプラグインをJSファイルとして外だししたい

そもそものはなし

#1

jQueryの基本的なつかいかた

$('div').fadeIn();

$('div').fadeOut();

(HTMLの)要素を取ってきて、それに対して処理を行う

jQueryプラグインって
なに?

#2

jQueryというライブラリに
新たな機能を追加(拡張)するためのカスタムメソッド

どうやってつくるの?

Step.1 | カスタムメソッドを拡張

// jQueryのprototypeというオブジェクト
$.fn;

// myPluginというカスタムメソッドを拡張(追加)
$.fn.myPlugin = function() {
	// ここに処理を書く
	・
	・
	・
};

Step.2 | 要素を変数に退避

//要素を退避
var elements = this;

Step.3 | 要素をループにかけてひとつずつ処理

// 要素をひとつずつ処理
elements.each(function() {
    // ここに処理を記述
    ・
    ・
    ・
});

なぜループが必要?

// 全てのdiv要素を取得
$('div');

// #hogeと#fooの二つの要素を取得
$('#hoge, #foo');

// .fugaの子要素を全て取得
$('ul.fuga').children();
  • jQueryオブジェクトは要素が複数あることが前提
  • 全ての要素に対して同様に処理しないといけない

each();で回して要素を一つずつ処理していく

Step.4 | method chain用に要素を返す

$.fn.myPlugin = function() {
	// ここに処理を書く
	・
	・
	・

	return this;
};

なぜreturnするのか?

なぜreturnするのか・・・

$('div')                 // div要素を取得
	.hide()              // 要素を隠す
	.text('new context') // テキストを書き換える
	.addClass('update')  // クラスを追加
	.show();             // 要素を表示

処理(method)を連結(chain)させたい

DEMO

jQueryプラグインに
オプションを渡す

#3

オプションの役割

プラグインの使い勝手を
高める

オプションの渡し方

$('#sprite').myPlugin({
	speed: 'fast',
	shakes: 10,
	x: 20
});

オブジェクト型で渡すのがセオリー

オプションの受け取り方

$.fn.myPlugin = function(options) {

	var elements = this;
	var opts = options;

	elements.each(function() {
		// optsの値を使って処理・・・
	}

引数を定義する

でも、これだと・・・

毎回引数を渡すのが必須になってしまい、使うのに手間がかかる・・・

ではどうすればいいか?

使い勝手を上げるために

プラグイン内にデフォルトのオプションをあらかじめ定義しておく

デフォルトオプション

$.fn.myPlugin.defaults = {
	speed: 'slow',
	shakes: 2,
	x: 50
};

渡されたオプションとデフォルトをマージ

$.fn.myPlugin = function(options) {

	var opts = $.extend(
		{},
		$.fn.myPlugin.defaults,
		options
	);

DEMO

jQUeryプラグインに
静的(static)関数を追加する

#4

静的(static)関数のメリット

jQueryセレクタを使わずに
処理を呼び出す事ができる

こんな風に使う事ができる

$.myPlugin.yurayura($('div'));

$.myPlugin.gakuburu($('div'));

引数として渡されたdiv要素で静的関数を呼び出す

静的(static)関数を追加する方法

Step.1 | 追加するためのベースを定義

$.myPlugin = {};

名前空間オブジェクトを追加して、そこに関数を定義

Step.2 | 静的(static)関数を定義

$.myPlugin.yurayura = function($obj) {
    var opts = {
        speed: 1000,
        shakes: 10,
        x: 20
    };
    doshake($obj, opts);
};

DEMO

jQueryプラグインを
JSファイルとして外だししたい

#5

外だしする方法

新規ファイルをつくって、
ソースをコピペして名前を付けて保存

外だしする上での注意点

$ショートカットが正常に動作するようにしておくこと

$ショートカット

$(‘div’) === jQuery(‘div’);

$();はjQuery();のエイリアスだけど・・・

$ショートカットはjQuery特有のモノではなく、prototype.jsなどでも普通に使われている

jQueryを他のライブラリと併用すると競合してしまう可能性がある

ではどうすればいいか?

プラグインのソースコード全体を匿名関数でラップしてしまえばいい

;(function($) {
	$.fn.myPlugin = function(options) {
		・
		・
		・
	};
}) (jQuery);

どうしてそうなる?

;(function($) {
	$.fn.myPlugin = function(options) {
		・
		・
		・
	};
}) (jQuery);

  • プラグイン全体を匿名関数でラップして即実行すると、$ショートカットは、そのプラグイン内でのみ有効となる
  • プラグインの外側では、そっちで$を通常通りに使える

補足

;(function($) {
	$.fn.myPlugin = function(options) {
		・
		・
		・

匿名関数の先頭にセミコロン(;)がついているけど、これは何?

$('div').hoge()

/* --------↑↑↑ 前に読み込んだライブラリ ↑↑↑-------- */
/* --------↓↓↓ 自作したライブラリ       ↓↓↓-------- */

(function($) {
	$.fn.myPlugin = function(options) {
		・
		・
		・

OK!

$('div').hoge() /* ← 前 | 自作 → */ (function($) {
		・
		・
		・

Error!

$('div').hoge() /* ← 前 | 自作 → */ ;(function($) {
		・
		・
		・

OK!

つけてて良かったセミコロン!(ゝω・)vキャピ

(ゝω・)v

直前に読み込んだライブラリの最後にセミコロン(;)が抜けていた場合の対策

DEMO

さらに・・・

プラグインを匿名関数でラップするとクロージャが作成される

クロージャが作成されると・・・

  • $ショートカットが他のライブラリと競合するのを防ぐ
  • 変数や関数が適切な名前空間において定義される

おわりに

世に出回っている超絶高機能なプラグインも、基本的な骨格は今回紹介したモノと同じ(※たぶん)

Thank you!

AWS Cloud Roadshow 2017 福岡