Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
jQuery逆引きリファレンス

jQuery逆引きリファレンス

jQueryプラグインを自作するには?($.fn)

2015年11月5日

何度も利用する似たコードは、ライブラリではなくプラグインにまとめよう。プラグイン作成の基本を解説。

  • このエントリーをはてなブックマークに追加

 jQueryでアプリを開発していて、似たようなコードを何度も見かけるようになってきたら、プラグイン化することを検討すべきです。本サイトでも、jQuery UIjQuery Mobileなどのプラグインを解説していますが、こうしたプラグインは(もちろん)自分でも作成できます。何度も利用するような機能は、無秩序に自己流の関数/クラスライブラリにしてしまうのではなく(ましてや、似たようなコードをコピペするのではなく)、プラグインとしてまとめることで、利用する際にも一貫性を維持でき、結果としてコードの見通しもよくなります。

 本稿では、confirmプラグインの作成を通じて、プラグインの基本を学びます。confirmプラグインは、ボタンクリック時に確認ダイアログを表示して、[OK]ボタンが選択された場合は後続の処理を継続し、[いいえ]ボタンが選択された場合には処理をキャンセルする、ごくシンプルなプラグインです。

confirmプラグインの使い方

 プラグインそのもののコードを解説する前に、イメージをつかみやすくするために、confirmプラグインを利用する側のコードを確認しておきます。

HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>jQuery TIPS</title>
</head>
<body>
<form>
  <div>
    <label for="keyword">キーワード:</label>
    <input id="keyword" type="text" size="20" />
    <input id="search" type="button" value="検索" />
  </div>
</form>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<!--confirmプラグインをインポート-->
<script src="jquery.confirm.js"></script>
<script>
$(function() {
  // confirmプラグインを適用
  $('#search')
   .confirm()
   // クリック時の挙動を定義
   .click(function() {
     console.log('処理が実行されました。');
   });
});
</script>
</body>
</html>
ボタンクリック時に確認ダイアログを表示するコード(confirm.html)
[キーワード]を入力して[検索]ボタンをクリック。<br>
これにより表示されるダイアログの[OK]/[キャンセル]ボタンをクリックすると……

[キーワード]を入力して[検索]ボタンをクリック。
これにより表示されるダイアログの[OK]/[キャンセル]ボタンをクリックすると……

確認ダイアログの選択によって後続の処理が実行されるかどうかも決まる

 確認ダイアログで[OK]ボタンをクリックした場合にだけ、ログが出力される(=後続のclickイベントが処理される)ことを確認してください。

 リストの太字部分に注目してみると、$(...).メソッド(...)というおなじみの形式でconfirmプラグインの機能を呼び出せることが確認できます。プラグインとして機能をまとめれば、コードにも一貫性が出ると述べた、これが理由です。

confirmプラグインの作成

 confirmプラグインの動作を確認できたところで、プラグイン本体のコードを確認してみましょう。

JavaScript
(function($) {
  $.fn.confirm = function() {
    this.click(function(e) {
      if(!confirm('処理を継続してよろしいですか?')) {
        e.preventDefault();
        e.stopImmediatePropagation();
      }
    });
    return this;
  };
})(jQuery);
confirmプラグインを動作するためのコード(jquery.confirm.js)

 短いコードですが、注目すべきポイントはさまざまです。

1「(function($) {...})(jQuery);」でくくること

 プラグインを作成する際、そこで利用している変数/関数はグローバルに公開すべきではありません。プラグイン作成にかかわらず、グローバルな名前空間の汚染を最大限防ぐことは、プログラミングの基本です。

 そこでプラグイン全体を、即時関数――(function($) {...})(jQuery);でくくることで、プラグインで利用する変数/関数を全てローカルスコープに押し込めることができます。

 即時関数の引数$に対して、明示的にjQueryを渡しているのは、他のライブラリ(例えばprototype.jsなど)との競合を防ぐためです。(function($) {...})(jQuery);とすることで、即時関数の中では$()jQuery()として利用できます。

[Note]即時関数

 JavaScriptでは、関数という単位でスコープが決定します。その性質を利用して、関数をスコープの枠組みとして使ってしまおうというのが、即時関数のアイデアです。(function($) { ... })のように関数を定義しておいて、その直後で即座に実行することから、そのように呼ばれます。

 即時関数の配下で定義された変数/関数は、全て関数スコープ(=ローカルスコープ)ですので、グローバルな名前空間を汚すことはありませんし、外から参照することもできません。

2「$.fn.メソッド名 = ~」でプラグインを定義

 $.fnは、jQueryオブジェクトのprototypeオブジェクトです。プラグインというと、いかにも特殊なものに思えますが、要は、標準のjQueryオブジェクトに対してインスタンスメソッドを拡張するということです。

 これには、$.fn.メソッド名 = function() { ... };のように表します。function() { ... }の配下では、thisでプラグインを呼び出したときのjQueryオブジェクトを表します。例えば、先ほどの例では、

$('#search').confirm()

としていましたので、this$('#search') ということです。プラグインの中で$('#search') のように決め打ちで対象の要素を表してしまうと、応用が利かなくなってしまいますので、対象の要素にはthisでアクセスする、と覚えておきましょう。

 なお、イベントリスナーの場合と異なり、thisはあくまで(標準の要素オブジェクトではなく)jQueryオブジェクトです。$(this)のようなラッピングは不要である点にも注意してください。

 ここでも、this.click~clickイベントリスナーを定義し、その中で確認ダイアログを表示するとともに、[キャンセル]ボタンがクリックされた場合にイベント処理をキャンセルしています。イベント処理の中断については、別稿「TIPS:イベント処理を中断するには?」も併せて参照してください。

3戻り値はjQueryオブジェクトを返す

 jQueryでは、$(...).attr(...).css(...)のように、関連するメソッドをドット演算子で順に連結して呼び出すことができます(メソッドチェーン)。メソッドチェーンは、jQueryメソッドが自分自身(jQueryオブジェクト)を返すことを利用した記法です。

 メソッドチェーンはjQueryの入門書などでも最初に語られる性質の1つで、プラグインを作成する上でも、メソッドチェーンの性質を損なわないことが求められます。つまり、プラグイン(メソッド)は特別に意味ある値を返すのでない限り*1jQueryオブジェクトを返すように書くのがお作法です。これには、プラグインメソッドの末尾でreturn this;とするだけです。先ほども触れたように、プラグインメソッドの中では、thisが操作対象の要素(jQueryオブジェクト)を表すのでした。

  • *1 例えばheight()のように、要素の高さを返すことを目的としたメソッドの場合は、例外です。
処理対象:基本 カテゴリ:プラグイン
API:jQuery.fn(jQueryプロトタイプオブジェクト) カテゴリ:内部処理(Internals)

※以下では、本稿の前後を合わせて5回分(第29回~第33回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

jQuery逆引きリファレンス
29. JavaScriptとHTMLを明確に分離するには?(data)

jQueryのdataメソッドを使って独自データ属性の値を取得することにより、「控えめなJavaScript」を実現する方法を説明する。

jQuery逆引きリファレンス
30. 特定の要素に関連付くデータを取得/設定するには?(data)

現在の要素に対して任意のデータを設定/取得するためのdataメソッドの基本と、利用上の注意点を解説する。

jQuery逆引きリファレンス
31. 【現在、表示中】≫ jQueryプラグインを自作するには?($.fn)

何度も利用する似たコードは、ライブラリではなくプラグインにまとめよう。プラグイン作成の基本を解説。

jQuery逆引きリファレンス
32. 自作のjQueryプラグインに引数を設定するには?($.extend)

プラグイン作成の基本を理解したら、パラメーターを受け取れるようにしよう。その実装方法を解説。

jQuery逆引きリファレンス
33. HTTP GET/POSTで非同期通信を実施するには?($.get/$.post)

$.get/$.postメソッドを使って取得したデータを加工して表示コンテンツを組み立てる方法を解説する。

サイトからのお知らせ

Twitterでつぶやこう!