2009年10月13日

jQuery pluginの開発規約について

本文(英語)のアドレス:
A Plugin Development Pattern » Learning jQuery - Tips, Techniques, Tutorials

結論から

まず、要点規約に沿ったソースを先頭に置きます。

  1. Claim only a single name in the jQuery namespace
  2. Accept an options argument to control plugin behavior
  3. Provide public access to default plugin settings
  4. Provide public access to secondary functions (as applicable)
  5. Keep private functions private
  6. Support the Metadata Plugin
// create closure
(function($) {
  // plugin definition
  $.fn.hilight = function(options) {
    debug(this);

    // build main options before element iteration
    var opts = $.extend({}, $.fn.hilight.defaults, options);

    // iterate and reformat each matched element
    return this.each(function() {
      $this = $(this);

      // build element specific options
      var o = $.meta ? $.extend({}, opts, $this.data()) : opts;

      // update element styles
      $this.css({
        backgroundColor: o.background,
        color: o.foreground
      });

      var markup = $this.html();
      // call our format function
      markup = $.fn.hilight.format(markup);
      $this.html(markup);
    });
  }

  // private function for debugging
  function debug($obj) {
    if (window.console && window.console.log)
      window.console.log('hilight selection count: ' + $obj.size());
  }

  // define and expose our format function
  $.fn.hilight.format = function(txt) {
    return '<strong>' + txt + '</strong>';
  }

  // plugin defaults
  $.fn.hilight.defaults = {
    foreground: 'red',
    background: 'yellow'
  }
// end of closure
})(jQuery);

解読

1. Claim only a single name in the jQuery namespace

プラグイン目的の純粋化と思われます。

// プラグインの宣言
$.fn.highlight = function() {
  // Our plugin implementation code goes here.
}
$('#myDiv').highlight();

以下はよくないパターンです。こうするなら二つのプラグインに分けるか、目的をもっと明確にしろうってことです。

$.fn.oneFunction= function() {};
$.fn.anotherFunction= function() {};

2. Accept an options argument to control plugin behavior

// プラグインの宣言
$.fn.highlight = function(options) {
  var defaults = {
    foreground: 'red',
    background: 'yellow'
  }
  // Extend our default options with those provided.
  var opts = $.extend(defaults, options);
  // Our plugin implementation code goes here.
}
$('#myDiv').highlight({
  foreground: 'blue'
});

3. Provide public access to default plugin settings

// プラグインの宣言
$.fn.highlight = function(options) {
  // Extend our default options with those provided.
  // Note that the first arg to extend is an empty object -
  // this is to keep from overriding our "defaults" object.
  var opts = $.extend({}, $.fn.highlight.defaults, options);
  // Our plugin implementation code goes here.
}

// plugin defaults - added as a property on our plugin function
$.fn.highlight.defaults = {
  foreground: 'red',
  background: 'yellow'
}
// override plugin default foreground color
$.fn.highlight.defaults.foreground = 'blue';
// ...
// invoke plugin using new defaults
$('.highlightDiv').highlight();
// ...
// override default by passing options to plugin method
$('#green').highlight({
  foreground: 'green'
})

4. Provide public access to secondary functions (as applicable)

例えば文字列をフォーマットするファンクション"format"があるとします。
ここでは単純に強調表示するだけですが、誰でも簡単に変更できます。

// プラグインの宣言
$.fn.highlight = function(options) {
  // iterate and reformat each matched element
  return this.each(function() {
    var $this = $(this);
    // ...
    var markup = $this.html();
    // call our format function
    markup = $.fn.highlight.format(markup);
    $this.html(markup);
  });
}

// define our format function
$.fn.highlight.format = function(txt) {
  return '<strong>' + txt + '</strong>';
}

5. Keep private functions private

// create closure
(function($) {
  // プラグインの宣言
  $.fn.highlight = function(options) {
    debug(this);
    // ...
  };

  // private function for debugging
  function debug(obj) {
   if (window.console && window.console.log)
     window.console.log('highlight selection count: ' + obj.size());
   }
   //  ...
// end of closure
})(jQuery);

6. Support the Metadata Plugin

Plugins/Metadata/metadata - jQuery Wiki

これはMetadataというプラグインがあるそうで、
なおかつたくさん人が使っていることを前提(或いは現状)としたため、
自分が作ったプラグインはMetadataにも対応するべきという結論になったわけです。

私もまだMetadataプラグインが何か全然わからないため、
ここはTODOとして残します。

Share on Twitter Share the post
Qihuan Piao

朴 起煥

東京で働いている「外人歴」9年のソフトウェア「ライター」。いつの間にか納豆が食えるようになり、これで日本に慣れきったと思いきやまだまだ驚きが続いてる。読んだり書いたりするのが好きで、自身の経験や本から得た「何か」をここに書き出してる。最近古本屋にハマってる。

他にも英語中国語で書いてます、よろしければチェックしてみてください。