非常に多くの人々が jQuery プラグインを開発しているため、より良い言語がないために 1 つが役に立たない状況に遭遇することは珍しくありません。サンプルやドキュメントがない、プラグインがベスト プラクティスに従っていないなど。しかし、あなたは幸運な人の 1 人です。この記事では、避けなければならない落とし穴について詳しく説明します。
Nettuts をよく使用する人にとって、jQuery は馴染みのないものではありません。 Jeffrey Way の 30 Days to Learn jQuery (およびここやその他の場所でのさまざまなチュートリアル) は素晴らしく、私たち全員を Sizzle を活用した Awesomesauce への道へと導きます。あらゆる誇大宣伝 (そして開発者やブラウザ ベンダーによる JavaScript の採用における大きな飛躍) の中で、大量のプラグインが登場しました。これが、jQuery が最も人気のある JavaScript ライブラリである理由の 1 つです。唯一の問題は、それらの多くがあまり良くないことです。
この記事では、特に JavaScript には焦点を当てず、プラグイン配信のベスト プラクティスに重点を置きます。
jQuery プラグインを作成する「正しい方法」として多かれ少なかれ広く受け入れられているパターンがいくつかあります。これらの規則に従わない場合、プラグインは...最悪になる可能性があります。最も一般的なパターンの 1 つを考えてみましょう:
リーリーまず、グローバル変数の使用を避けるために、自己呼び出しの匿名関数を作成します。 $
、window
、および 未定義
を渡します。自己呼び出し関数への引数は jQuery
と window
です。未定義には何も渡されないため、プラグインで未定義キーワードを使用することにした場合、実際には「未定義」になります。は未定義です。
これにより、他のスクリプトが
true
! などの悪意のある値をunknown
に割り当てる可能性を防ぐことができます。
$
jQuery として渡されます。これは、$
が匿名関数の外部にあるプロトタイプなど、他のものを完全に参照できることを保証するために行われます。
グローバルにアクセス可能な window
オブジェクトの変数を渡すと、縮小プロセスを通じてより多くのコードを圧縮できます (これも実行する必要があります)。
次に、jQuery プラグイン モード $.fn.PluginName
を使用します。 $(selector).method()
形式を使用するプラグインを登録する方法です。 jQuery のプロトタイプを新しいメソッドで拡張するだけです。 jQuery オブジェクトの関数を定義するプラグインを作成する場合は、次のように直接追加します。
jQuery オブジェクトのプロパティとして定義された関数は通常、jQuery オブジェクトを返さないため、このタイプのプラグインはリンクできません。たとえば、次のコードを考えてみましょう:
リーリーここでは、文字列の配列を返します。おそらくユーザーはそれを使いたいと思うので、単純にそれを配列として返すのが合理的です (必要に応じて、それを jQuery オブジェクトに簡単にラップできます)。代わりに、次の不自然な例を考えてみましょう:
リーリー この場合、ユーザーは $.getOddEls
から返される jQuery オブジェクトを期待する可能性があるため、渡された関数によって定義された jQuery コレクションを返すフィルター メソッドを返します。経験則としては、返された要素を jQuery 関数でラップすることです (特に、連鎖できる場合)。配列、文字列、数値、関数、またはその他のデータ型を返す場合は、開いたままにしておきます。
おそらく、コードを公開するときに行うことができる最も重要なことは、必要なドキュメントを追加することです。開発者に説明する内容と、コードが実際に行うことまたは実行できることの間にギャップがあるため、ユーザーはコードの詳細を理解するのに時間を無駄にしたくないのです。
ドキュメントの作成には厳密なルールはありませんが、(よく整理された)ドキュメントが多ければ多いほど良いと一般に認められています。
このプロセスは、内部実践 (コード内/コード全体に散在) と外部実践 (Wiki または Readme ファイル内のすべてのパブリック メソッド、オプション、および複数の使用例の徹底的な説明) の両方である必要があります。
最も人気のあるプラグインは、ユーザーが制御したい変数 (ほとんどのプラグインでは「オプション」オブジェクトと呼ばれます) への完全なアクセスを提供します。また、さまざまなコンテキストで再利用できるように、プラグインのさまざまな構成を提供することもあります。たとえば、単純なスライダー プラグインを考えてみましょう。ユーザーが制御したいオプションには、アニメーションの速度、タイプ、遅延が含まれます。
プラグインによって挿入または操作される DOM 要素に追加されたクラス/ID 名へのアクセスもユーザーに与えることをお勧めします。ただし、さらに、スライドの遷移ごと、またはスライドが最初に戻るとき (完全な「ループ」) にコールバック関数にアクセスしたい場合もあります。
あなたの仕事は、プラグインのあらゆる用途とニーズを考慮することです。
別の例を考えてみましょう。API を呼び出すプラグインは、API の戻りオブジェクトへのアクセスを提供する必要があります。次の単純なプラグインの概念を例として取り上げます:
$.fn.getFlickr = function(opts) { return this.each(function(){ // jQuery chainability var defaults = { // setting your default options cb : function(data){}, flickrUrl : // some default value for an API call } // extend the options from defaults with user's options var options = $.extend(defaults, opts || {}); // call the async function and then call the callback // passing in the api object that was returned $.ajax(flickrUrl, function(dataReturned){ options.cb.call(this, dataReturned); }); }); }
这使我们能够做以下事情:
$(selector).getFlickr(function(fdata){ // flickr data is in the fdata object });
宣传这一点的另一种方式是提供“钩子”作为选项。从 jQuery 1.7.1 及更高版本开始,我们可以在插件调用之后使用 .on(eventName, function(){})
将行为分离到它们自己的函数中。例如,使用上面的插件,我们可以将代码更改为如下所示:
$.fn.getFlickr = function(opts) { return this.each(function(i,el){ var $this = el; var defaults = { // setting your default options flickrUrl : "http://someurl.com" // some default value for an API call } var options = $.extend(defaults, opts || {}); // call the async function and then call the callback // passing in the api object that was returned $.ajax(flickrUrl, function(dataReturned){ // do some stuff $this.trigger("callback", dataReturned); }).error(function(){ $this.trigger("error", dataReturned); }); }); }
这允许我们调用 getFlickr
插件并链接其他行为处理程序。
$(selector).getFlickr(opts).on("callback", function(data){ // do stuff }).on("error", function(){ // handle an error });
您可以看到提供这种灵活性绝对重要;您的插件的操作越复杂,可用的控件就越复杂。
好的,第三条建议是,您的插件的操作越复杂,可用的控制就越复杂。可用。然而,一个很大的错误是为插件功能提供了太多的选项。例如,基于 UI 的插件最好具有无参数默认行为。
$(selector).myPlugin();
当然,有时这是不现实的(例如,用户可能正在获取特定的提要)。在这种情况下,您应该为他们做一些繁重的工作。有多种方式将选项传递给插件。例如,假设我们有一个简单的推文获取器插件。该推文获取器应该有一个默认行为,带有一个必需选项(您要从中获取的用户名)。
$(selector).fetchTweets("jcutrell");
例如,默认情况下可能会抓取一条推文,将其包装在段落标记中,然后使用该 html 填充选择器元素。这是大多数开发人员所期望和欣赏的行为。细粒度选项应该就是:选项。
当然,根据插件的类型,如果高度基于 UI 操作,则必须包含 CSS 文件,这是不可避免的。一般来说,这是一个可以接受的问题解决方案;大多数插件都与图像和 CSS 捆绑在一起。但不要忘记第二点 - 文档还应包括如何使用/引用样式表和图像。开发人员不想浪费时间查看源代码来弄清楚这些事情。
事情应该只是......工作。
话虽如此,使用注入样式(可以通过插件选项高度访问)或基于类/ID 的样式绝对是最佳实践。这些 ID 和类也应该可以通过前面提到的选项进行访问。然而,内联样式会覆盖外部 CSS 规则;不鼓励将两者混合使用,因为开发人员可能需要很长时间才能弄清楚为什么插件创建的元素不遵守他们的 CSS 规则。在这些情况下请运用您的最佳判断。
根据经验,内联 CSS 很糟糕 - 除非它很小到无法保证有自己的外部样式表。
证据就在布丁中:如果您无法提供一个实际示例来说明您的插件如何使用随附的代码,人们很快就会放弃使用您的插件。就那么简单。不要偷懒。
一个很好的示例模板:
jQuery,像任何优秀的代码库一样,随着每个版本的发布而成长。即使在弃用支持后,大多数方法仍会保留。然而,添加了新的方法;一个完美的例子是 .on()
方法,它是 jQuery 的新的事件委托一体化解决方案。如果您编写一个使用 .on()
的插件,那么使用 jQuery 1.6 或更早版本的人将不走运。现在,我并不是建议您针对最低公分母进行编码,但是,在您的文档中,请务必解释您的插件支持哪个版本的 jQuery。如果您引入了支持 jQuery 1.7 的插件,那么即使 1.8 发布,您也应该强烈考虑维持对 1.7 的支持。您还应该考虑利用 jQuery 中新的/更好的/更快的功能。
鼓励开发人员升级,但不要太频繁地破坏您的插件!一种选择是提供插件的“旧版”、已弃用、不受支持的版本。
如果您还没有学会如何使用版本控制,那么是时候咬紧牙关了。
除了将 jQuery 版本支持/兼容性作为文档的一部分之外,您还应该进行版本控制。版本控制(具体来说,通过 GitHub)在很大程度上是社交编码的发源地。如果您正在开发一个 jQuery 插件并希望最终发布到官方存储库中,那么无论如何它都必须存储在 GitHub 存储库中;如果您还没有学会如何使用版本控制,那么是时候硬着头皮了。版本控制有无数的好处,所有这些都超出了本文的范围。但核心好处之一是,它允许人们查看您所做的更改、改进和兼容性修复以及您何时进行这些更改、改进和兼容性修复。这也为您编写的插件的贡献和定制/扩展打开了大门。
世界不需要另一个滑块插件。
好吧,我们在这里忽略它已经足够长的时间了:一些“插件”是无用的或太浅,不足以保证被称为插件。世界不需要另一个滑块插件!然而,应该指出的是,内部团队可能会开发自己的插件供自己使用,这是完全可以的。但是,如果您希望将您的插件推向社交编码领域,请找到编写更多代码的理由。俗话说,没有理由重新发明轮子。相反,接过别人的方向盘,建造一辆赛车。当然,有时会有新的、更好的方法来做已经做过的同样的事情。例如,如果您使用更快或新技术,您很可能会编写一个新的滑块插件。
这个相当简单:提供代码的缩小版本。这使得它更小、更快。它还确保您的 Javascript 在编译时不会出现错误。当您缩小代码时,不要忘记也提供未压缩的版本,以便您的同行可以查看底层代码。对于各种经验水平的前端开发人员来说,都有免费且廉价的工具。
有关自动化解决方案,请参阅提示十三。
当你编写一个插件时,它的目的就是供其他人使用,对吗?因此,最有效的源代码是具有高度可读性的。如果您正在编写无数巧妙的单行 lambda 样式函数,或者您的变量名称没有语义,那么当错误不可避免地发生时,将很难对其进行调试。不要编写短变量名来节省空间,而是遵循技巧九(缩小!)中的建议。这是优秀文档的另一部分;优秀的开发人员应该能够检查您的代码并了解其用途,而无需花费太多精力。
如果您发现自己调用变量“
a
”或“x
”,那么您就做错了。
此外,如果您发现自己查阅文档来记住您自己的看起来奇怪的代码正在做什么,那么您也可能需要不那么简洁并更具解释性。将每个函数的行数限制为尽可能少;如果它们延伸三十行或更多行,则可能会有代码味道。
尽管我们都喜欢使用 jQuery,但重要的是要了解它是一个库,而且成本很小。一般来说,您不需要太担心 jQuery 选择器性能之类的事情。不要令人讨厌,你会没事的。 jQuery 是高度优化的。也就是说,如果您需要 jQuery(或插件)的唯一原因是在 DOM 上执行一些查询,您可能会考虑完全删除抽象,而坚持使用普通 JavaScript 或 Zepto。
注意:如果您决定坚持使用普通 JavaScript,请确保您使用的是跨浏览器的方法。对于较新的 API,您可能需要一个小型的 polyfill。
使用咕噜声。期间。
Grunt 是一个“用于 JavaScript 项目的基于任务的命令行构建工具”,最近在 Nettuts+ 上对此进行了详细介绍。它允许你做这样的事情:
grunt init:jquery
此行(在命令行中执行)将提示您一系列问题,例如标题、描述、版本、git 存储库、许可证等。这些信息有助于自动化设置文档、许可等的过程。
Grunt 所做的不仅仅是为您制作一些定制的样板代码;它还提供内置工具,例如代码 linter JSHint,只要您安装了 PhantomJS(由 Grunt 负责),它就可以为您自动执行 QUnit 测试。这样,您可以简化工作流程,因为测试在保存时会立即在终端中运行。
ああ、ところで - コードをテストしましたよね?そうでない場合、コードが期待どおりに動作することをどのように確認/主張しますか?手動テストも有効ですが、1 時間に何度もブラウザを更新していることに気付いたら、それは間違っています。 QUnit、Jasmine、さらには Mocha などのツールの使用を検討してください。
テストは、GitHub でプル リクエストをマージする場合に特に役立ちます。新しいコードや変更されたコードが既存のプラグインを破壊しないことを確認するために、すべてのリクエストにテストの提供を要求できます。
jQuery プラグインのテストの概念が初めての場合は、プレミアム限定のスクリーンキャスト「jQuery プラグインを駆動するテクノロジーのテスト」を視聴することを検討してください。さらに、今週後半に Web サイトで新しい JavaScript Testing with Jasmine コースを開始します。
以上がjQuery プラグインが使用されない理由として考えられる 14 の説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。