position: absolute;

とりあえずjQueryのプラグイン作ってみる

このエントリーはjQuery Advent Calendar 2013の18日目になります。

jQueryのプラグインといえば何かしらお世話になっている人がほとんどだと思いますが、自分で作成するというのもできるのでとりあえずサクッと作ることができる範囲で紹介します。

という導入ですので、比較的軽い内容になりますー。

jQueryプラグインを作る?

別に作って公開して世界中で使ってもらえという話ではないです。たとえば自分や会社内でよく利用する機能とか、比較的jQeryを利用したJavaScriptのプログラム群が大きくなってきたという時にプラグイン化してしまえば、他の機会に使いやすくなったり、意図せず他のプログラムに影響を与えてしまうということが避けられたりとメリットが結構あります。

プラグイン化するというのはパッケージにしてしまうということなので、プログラム群から独立して活用できますし、オブジェクトが他に影響を与えるリスクを大きく軽減してくれるのです。

では作ってみよう

まず、公式サイトにHow to Create a Basic Pluginというドキュメントがあるのでそこを読んで頂くのが手っ取り早いのですが、それではこのエントリーの意味が無いので、さらに手っ取り早く乱暴にまとめることにします。(なのでじっくり行きたい人は前述のドキュメントのステップを踏んでください)

今回作成したサンプルはaタグに対して、ドメインが違うリンクに対してはtarget="_blank"を付与した上で、リンクのテキストにドメイン名を追加するというものです。では、手っ取り早い感じで手順をまとめてみます。

軽微なプラグインのひな形

今回のような単機能のプラグインを作成する場合のひな形は下記のような感じです。

(function($){
    $.fn.yourPluginsName = function(){
        return this.each(function(){
            // この中に機能を記述
        });
    };
}(jQuery));

ポイントは何点か、まず

(function($){
    // 略
}(jQuery));

は、JavaScriptで言う「即時関数」です。名前の通りこの記述の中は読み込まれた時点で実行が始まるというものですが、それ以外の効果として、この中で記述された変数やfunctionなどオブジェクトは内部だけで完結します。なので、この中で記述されたものが他のプログラムに影響を与えないということが確保できます。ただ、それであればプラグインとしてjQueryのオブジェクトに格納されないので、後ろのカッコの中にjQueryオブジェクトを与えて$変数として内部に受け取るという記述をししています。

// 略
    $.fn.yourPluginsName = function(){
// 略

この中のyourPluginsNameというところがプラグインの機能名になります。ここだけは他のものと被らないように気をつけましょう。なにか自分だけのプリフィックスをつけるのも手だと思います。

// 略
        return this.each(function(){
// 略

で、大事なのはこの部分のreturn。こういう形で記述することで、jQueryのメソッドチェーンの中に組み込むことができます。これがなくともプラグインとしては成立しますが、今回のような単機能型のプラグインだとメソッドチェーンの中で使えないと不便きわまりないので忘れないようにしましょう。eachを利用しているのは対象の要素が複数の場合にそれぞれに対して動作するためで、これは対象が単独であっても同じように動作します。

ちょっと「手っ取り早く」から外れますが、ここのthisはjQueryオブジェクトになっていますので、$(this)と書かないようにしましょう。ただし、eachのfunctionの中のthisはjQueryオブジェクトではないので、ここは混同しないように注意してください。

で機能を作成する

今回紹介したひな形を利用して作成したプラグインは

(function($){
    $.fn.addLinkDomain = function(){
        return this.each(function(){
            var $this  = $(this),
                url    = '',
                domain = '';
            if ($this.is('a')){
                url = this.href;
                if (/^https?:\/\/.+/.test(url)){
                    domain = url.split('/')[2];
                    if (domain !== location.hostname){
                        $this.attr('target','_blank').append('(' + domain + ')');
                    }
                }
            }
        });
    };
}(jQuery));

こんな感じになりました。

  1. aタグである確認
  2. リンク先がhttp(s)://で記述しているかの確認
  3. 現在のページとドメインが違うかの確認
  4. target="_blank"の挿入
  5. ドメインの文字列の挿入

を行っています。(thisとeachの間にfilter噛まして最適化とかありますけど、ひな形から外れるのであえてここまでで)

あとは、jQueryと作成したプラグインを読み込んで、プラグインの機能名をjQueryの他の機能群と同じように使用します。

<script src="js/jquery-1.10.2.min.js"></script>
<script src="js/testplugin.js"></script>
<script>
$(function(){
    $('a').addLinkDomain();
});
</script>

はい!以上!

以下が補足です。

  • プラグインの記述は1ファイルに1つでなくて構わないので、1つのファイルに複数のプラグインを作成してまとめて問題無いです。
  • もう少し複雑なプラグインは公式サイトのAdvanced Plugin Conceptsや、多分最終日に西畑さんが紹介されるのでは(「jQueryプラグインのメソッドパターンについて書くかもしれない!」とあるので…)?と思うのでそちらを参照してください。

というわけで以上です。ありがとうございました!