JQueryプラグインを作成するための良いトーンルール

JQueryプラグインを作成するための良いトーンルール 大量のjQueryプラグインを作成しました。 すべてのプラグインのコードを見て、GitHubでの公開日でソートすると、コードの進化を追跡できます。 これらのプラグインはいずれも、以下で説明するすべての推奨事項に準拠していません。 説明するのは、プロジェクトごとに得た個人的な経験だけです。

jQueryでの拡張機能の記述は非常に簡単ですが、後で保守および拡張しやすいように拡張機能の記述方法を学びたい場合は、catにようこそ。




次は一連の推奨事項です。 読者はjQueryプラグインの開発に精通していることを前提としています。 ただし、jQueryプラグインの例は引き続き提供しますが、その構造は通常、関連記事で推奨されています。



(function ($) { $.fn.tooltips = function (opt) { var options = $.extend(true, { position: 'top' }, opt); return this.each(function () { $(this).after('<div class="xd_tooltips ' + options.position + '">' + $(this).data('title') + '</div>'); }); }; }(jQuery));
      
      





これがプラグインのすべての機能です。 各選択項目の後に、 div.xd_tooltipsが新しい項目を追加します。 それが彼のすべてです。



すべての操作は別のクラスで実行する必要があります。



成長する深刻なプラグインを考案したので、例のように、各メソッドですべてのロジックを匿名関数に入れる必要はありません。 別のコンストラクター関数(クラス)を作成します。 次に、選択した要素ごとに、このクラスの個別のインスタンスを作成し、元の要素のデータにそのクラスへのリンクを保存します。 プラグインを再度呼び出すと、 データがチェックされます 。 これにより、再初期化の問題が解決します。



 (function ($) { var Tooltips = function (elm) { $(elm).after('<div class="xd_tooltips">' + $(elm).data('title') + '</div>'); }; $.fn.tooltips = function (opt) { var options = $.extend(true, { position: 'top' }, opt); return this.each(function () { if (!$(this).data('tooltips')) { $(this).data('tooltips', new Tooltips(this, options)); } }); }; }(jQuery));
      
      





クラスメソッドを使用して、hide、show、destroyの一般的な操作をすべて実行します。



プラグインが大きく、その機能の一部を別のプラグイン/コードで使用する場合、クラスに利用可能なパブリックメソッドがある場合、非常に便利です。 メソッドはプロトタイプを介して実行できますが、マイナスがあります-プライベート変数は使用できません。 より良いオプションは、ローカル関数を使用することです。これにより、ハッシュで返されます。



このようなもの:

 //  ,     this var PluginName = function () { this.init = function () { //  }; }; // ,      //      this var PluginName = function () {}; PluginName.prototype.init = function () { //  }; //  var PluginName = function () { var self, init = function () { //  }; self = { init: init }; return self; };
      
      





3番目のオプションが最適なのはなぜですか?

まず、クラス内にこのプレフィックスなしで使用できるメソッドがあります。 これ -悪の手では悪です。 JSでは、何でも構いません。可能な限り使用しないことを強くお勧めします。



次に、プラグインが大きい場合、プラグインをuglifyに渡すことにします 。 後者の場合、initへのすべての参照(ハッシュキーself.initを除く )は、1文字の変数に置き換えられます。この変数は、メソッドが頻繁に使用されると、コードをかなり削減します。



3番目に、プライベートメソッドと変数を使用できます。これらは、上部のvarで宣言します。 とても便利です。 「アダルト」YaPのプライベートメソッドのようなもの。



最後のルールから、もう1つ絞る必要があります。



オブジェクトの初期化はすべて、別のinitメソッドで保持する必要があります



クラスのインスタンスを作成するときは、可能な限り何もしないでください。 これは単なる経験です。 プラグインは遅かれ早かれ成長し、jQueryからではなく、別の場所からコードを使用したくなるでしょう。 たとえば、コードにクールなパーサーがあり、それをDOM要素の外部で使用したい場合があります。



次に:



 var tooltips = new Tooltips(); tooltips.parse(somedata);
      
      





DOMツリーには何も作成しませんが、必要なことは正確に行います。



クラスのインスタンスごとに個別の設定インスタンスを作成します



最初の例では、1つのグローバルオプション変数を作成しました。 また、jQueryのスコープでは、いくつかのオブジェクトを取得できます。 脅威を感じますか? JSは、要素の1つがこれらのオプションを変更すると、すべての要素で変更されるように機能します。 これは必ずしも真実ではありません。 したがって、 オプションは 、クラスのコンストラクターの2番目の要素として機能します



上記から、プラグインは次のようになります。



 (function ($) { var Tooltips = function (elm, options) { var self, init = function () { $(elm).after('<div class="xd_tooltips ' + options.position + '">' + $(elm).data('title') + '</div>'); }; self = { init: init }; return self; }; $.fn.tooltips = function (opt) { return this.each(function () { var tooltip; if (!$(this).data('tooltips')) { tooltip = new Tooltips(this, $.extend(true, { position: 'top' }, opt)); tooltip.init(); $(this).data('tooltips', tooltip); } }); }; }(jQuery));
      
      





デフォルト設定はグローバルに表示されるはずです。



上記の例では、opt設定とデフォルト設定をハッシュ{}の形式で組み合わせています。 これは正しくありません-そのような設定が機能しないユーザーは常に存在し、その設定でプラグインを毎回呼び出す必要はありません。 もちろん、彼はプラグインコードに入り、自分で設定を修正できますが、プラグインの更新は失われます。 したがって、デフォルト設定はグローバルに表示される必要があり、グローバルに変更することもできます。



プラグインでは、次のように使用できます。



 $.fn.tooltips = function (opt) { return this.each(function () { var tooltip; if (!$(this).data('tooltips')) { tooltip = new Tooltips(this, $.fn.tooltips.defaultOptions, opt); tooltip.init(); $(this).data('tooltips', tooltip); } }); }; $.fn.tooltips.defaultOptions = { position: 'top' };
      
      





その後、開発者はスクリプトで宣言できます。



 $.fn.tooltips.defaultOptions.position = 'left';
      
      





プラグインが初期化されるたびにこれを実行しないでください。



常にこれを返さないでください



上記のすべての例で、初期化コードは、すぐにthis.eachを返したという事実に基づいています。 実際、ほぼすべてのjQueryメソッド(プラグイン)がthisを返します



したがって、次のようなことが可能です。



 $('.tooltips') .css('position', 'absolute') .show() .append('<div>1</div>');
      
      





とても便利です。 しかし、たとえば、 valメソッドは、パラメーターがない場合、要素の値を返します。 そのため、プラグインが値を返す方法を提供する必要があります。



 $.fn.tooltips = function (opt, opt2) { var result = this; this.each(function () { var tooltip; if (!$(this).data('tooltips')) { tooltip = new Tooltips(this, $.fn.tooltips.defaultOptions, opt); tooltip.init(); $(this).data('tooltips', tooltip); } else { tooltip = $(this).data('tooltips'); } if ($.type(opt) === 'string' && tooltip[opt] !== undefined && $.isFunction(tooltip[opt])) { result = tooltip[opt](opt2); } }); return result; };
      
      





2番目のopt2パラメーターが追加されていることに注意してください。 いくつかのメソッドが呼び出される場合に正確に必要になります。

たとえば、I / Oプラグインの場合、元のを変更することが重要です



 $('input[type=date]').datetimepicker(); $('input[type=date]').datetimepicker('setValue', '12.02.2016'); console.log($('input[type=date]').datetimepicker('getValue'));
      
      





「use strict」を使用する



真剣に、あなたは使っていませんか? JSは許しすぎて、ここから膨大な量のエラーが発生します。 このディレクティブを使用すると、少なくともグローバル変数からあなたを救います。



 (function ($) { 'use strict'; //... } (jQuery));
      
      





ファイルの最初に「use strict」を宣言できると誰かが言うだろうが、これを行うことはお勧めしない。 プロジェクトが成長すると、他のプラグインがそれを使用します。 そして、これらのプラグインの作成者は「スクリプトを使用」を使用しませんでした。 grunt / gulp / npmがすべてのパッケージを単一のビルドファイルに収集すると、不愉快な驚きがあります。



コードの検証にはJSLintを強くお勧めします。 私は長年開発にメモ帳++を使用してきましたが、エラーの強調表示はありません。 IDEには関係ないかもしれませんが、JSLintを使用するとより良いコードを書くことができます。



内部CSSリセットを使用する



CSSファイルの先頭で、プラグイン全体のすべてのCSSをゼロにします。 つまり メインクラスが必要で、その下に他の全員がいます。 Lessを使用する場合、これにより、読みやすくなります。



 .jodit { font-family: Helvetica, Arial, Verdana, Tahoma, sans-serif; &, & *{ box-sizing: border-box; padding:0; margin: 0; } }
      
      





CSSクラス名にプレフィックスを使用する



ブラウザのCSSはグローバルなものです。 また、プラグインがどのような環境になるかを予測することは不可能です。 したがって、マイナークラスも含めて、すべてプレフィックスを付けて記述します。 私は、補助クラスがプラグインの外観を完全に無効にする、アクティブにする、ホバーする方法をよく見ました。



最新のプロジェクトビルド方法を使用する



コメントは、最新のJSプロジェクトは、更新、自動ビルダー、依存関係の追跡なしでは存続できないことを正しく示唆しました。

コードでは、jQueryはすでにプロジェクトに接続されていると単純に信じていました。 しかし、これがそうでない場合はどうでしょう。 すべてが壊れます。

 ;(function (factory) { if (typeof define === 'function' && define.amd) { // AMD define(['jquery'], factory); } else if (typeof exports === 'object') { // Node/CommonJS  Browserify module.exports = factory; } else { //     factory(jQuery); } }(function ($) { 'use script'; //   }));
      
      





ブラウザでのこのようなスクリプトはデフォルトで以前と同じように機能しますが、Browserifyおよび同様のシステムを使用すると、必要な依存関係がすべて自動的に強化されます。 そして、ここではjQueryだけではありません。 その他のライブラリ。



bowerとnpmでプロジェクトを登録します



深刻な人は、プラグインにアップグレード機能がない限り、プラグインを使用しません。 githubを使用したプラグインアーカイブのダウンロードは、すでに昨日です。 今、 npmjs.comに登録するだけです

次に、プロジェクトのルートで実行します

 npm init
      
      





そして、指示に従ってください。 プロジェクトのルートに、 package.jsonが表示されます。

その後、チーム

 npm publish ./
      
      





同じ場所から、npmでプラグインを公開します。



そして、エンドユーザーは次のように自分でインストールできます:

 npm install tooltips
      
      





新しいバージョンごとにnpm publish ./を実行する必要があります。 これはあまり便利ではありませんが、その前に「git」コマンドをたくさん入力する必要があります。



私自身は、 package.jsonを使用してこのプロセスを自動化しました。 次のようなコマンドをフィールドに追加しました。

 "version": "1.0.0", "scripts": { "github": "git add --all && git commit -m \"New version %npm_package_version%\" && git tag %npm_package_version% && git push --tags origin HEAD:master && npm publish", },
      
      





そして実行するだけです:

 npm run github
      
      





すべてのファイルをgitに追加し、 コミットし 、現在のバージョンのタグを作成し、すべてをgithubにアップロードしてから、バージョンをnpmjsに更新します。

package.jsonからバージョンを取得し 、各呼び出しの前に更新する必要があります。 ただし、 git addの前に、先頭に追加するだけでこれを自動化できます。

 npm version patch
      
      





私はWindowsで作業しているので、 package.json変数は次のように使用されます- %npm_package_version% 、他のOSでは$ npm_package_versionを使用する必要があります

バウアーにとって、状況はほとんど同じです。 登録する場所はありません。

まだbowerをインストールしていない場合。

 npm install -g bower
      
      





それから

 bower init
      
      





プロジェクトのルート。

bower.jsonが作成されたら、githubまたは別のホスティングサービスですべてを公開します。



その後、パッケージを登録できます。

 bower register jodit https://github.com/xdan/jodit.git
      
      







これですべてです。コメントにヒントを書いてください。 ご清聴ありがとうございました!



All Articles