jQueryプラグインの開発方法とは何ですか?オブジェクト指向メソッドを使用して、安全で、適切に構造化され、よく整理された jQuery プラグインを作成するにはどうすればよいでしょうか?以下はphp中国語サイトで共有されている技術記事です。
本文:
jQuery の使い方を学ぶのはシンプルで簡単なので難しいことではありません。jQuery に触れてからは、多くのプラグインを使用したり、使い慣れたりしていると思います。機能をより高いレベルに向上させたい場合は、独自のプラグインを作成するのが良い選択かもしれません。
まず理解しましょう: jQuery プラグイン開発モデル:
ソフトウェア開発プロセスには、開発をガイドするための特定の設計パターンが必要です。パターンを使用すると、コードをより適切に整理でき、以前から多くの優れたプラクティスを学びました。人々がまとめたモデル。
jQueryプラグインの開発方法とは何ですか?
「jQuery Advanced Programming」の説明によると、jQuery プラグインを開発するには主に 3 つの方法があります。
1. $.extend() を使用して jQuery を拡張する 2. jQuery に新しいメソッドを追加する。 $.fn 経由;
3. jQuery UI のウィジェット ファクトリ メソッドを使用して、$.widget() 経由で作成します。
通常、簡単なプラグイン開発には 2 番目の方法を使用しますが、3 番目の方法に比べて簡単だと言われています。 3 番目の方法は、より高度な jQuery コンポーネントを開発するために使用されます。このモードで開発されたコンポーネントには、プラグインのステータス情報の自動保存、プラグインに関するさまざまな一般的なメソッドなど、jQuery の多くの組み込み機能が含まれています。ここでは詳細には触れません。
最初の方法は単純すぎます。jQuery 名前空間に静的メソッドを追加するか、jQuery として理解するだけです。したがって、$.extend() を通じて追加された関数を呼び出すときは、DOM 要素 ($('#example').myfunction()) を選択せずに、$ シンボル ($.myfunction()) を通じて直接呼び出します。以下の例を参照してください。
$.extend({ sayHello: function(name) { console.log('Hello,' + (name ? name : 'Dude') + '!'); } }) $.sayHello(); //Hello Dude $.sayHello('Wayou'); //Hello Wayou
上記のコードでは、sayHello 関数が $.extend() を通じて jQuery に追加され、$ を通じて直接呼び出されます。この時点で、単純な jQuery プラグインが完成したと考えることができます。ただし、ご覧のとおり、いくつかのヘルパー メソッドを定義する場合は、この方法の方が便利です。
1. 基本的なプラグイン開発:(1) プラグインの記述構文 (形式)
$.fn.myPlugin = function() { //具体代码 } $("元素").myPlugin(); //调用编写的插件,类似于jquery一样。
$("element").myPlugin(); // 記述されたプラグインを呼び出します。 jクエリ。
上記のコードを通して、プラグインを記述する方法は基本的に $.fn にメソッドを追加することであることがわかります。プラグインの名前は私たち自身が付けたものであり、その後、プラグインが付けられます。コード内のコードはこのメソッドで展開されます。
たとえば、ページ上のすべてのリンクの色を赤に変更する場合、次のようにプラグインを作成できます:
プラグイン名で定義された関数内で、これは、プラグインを呼び出すときの jQuery セレクター。通常は jQuery タイプのコレクションです。
たとえば、$('a') はページ上のすべての a タグのコレクションを返します。このコレクションはすでに jQuery パッケージ化タイプになっています。つまり、これを操作するときに、代わりに他の jQuery メソッドを直接呼び出すことができます。 of を再度ドル記号で囲む必要があります。
そのため、上記のプラグイン コードでは、これに対して jQuery の css() メソッドを呼び出します。これは $('a').css() を呼び出すのと同じです。
この場所の意味を理解することが重要です。このようにすると、なぜ jQuery メソッドを商業的に直接使用できるのかがわかります。同時に、この参照が他の場所で異なる場合は、それを呼び出すために jQuery で再パッケージ化する必要があります。これについては後述します。初心者はこの値に戸惑いやすいですが、理解すればそれほど難しいことではありません。
これで、ページにアクセスしてコードを試してみることができます。プラグインを呼び出すと、リンクのフォントが赤になります。
<ul> <li> <a href="http://blog.sina.com.cn/u/3138089525">我的微博</a> </li> <li> <a href="http://http://www.zymseo.com">我的博客</a> </li> <li> <a href="http://web.zymseo.com">我的小站</a> </li> </ul> <p>这是p标签不是a标签,我不会受影响</p> <script src="jquery-1.11.0.min.js"></script> <script src="jquery.myplugin.js"></script> <script type="text/javascript"> $(function(){ $('a').myPlugin(); }); </script>
実行結果は次のとおりです:
$.fn.myPlugin プラグイン開発
次のステップでは、コレクションを処理するのではなく、プラグイン コード内の特定の要素をそれぞれ処理します。各要素に対応する操作を実行できることを確認します。
これが jQuery セレクターによって返されたコレクションを参照していることはすでにわかっているので、jQuery の .each() メソッドを呼び出すことでコレクション内の各要素を処理できますが、この時点で注意しなければならないのは、それぞれの内部のjQuery メソッドを呼び出す必要がある場合は、$ を使用して再パッケージ化する必要があります。
たとえば、各リンク内のリンクの実際のアドレスを表示したいとします。まず、それぞれの a タグをすべて走査し、次に href 属性の値を取得して、それをリンク テキストの末尾に追加します。
変更後のプラグイン コードは次のようになります:
$.fn.myPlugin = function() { //在这里面,this指的是用jQuery选中的元素 this.css('color', 'red'); this.each(function() { //对每个元素进行操作 $(this).append(' ' + $(this).attr('href')); }); }
この時点で、簡単な関数を備えた jQuery プラグインを作成できます。そんなに難しくないですか? jQuery プラグインの作成の重要な部分であるパラメーターの受信から始めましょう。
(2) プラグインを強力にする(パラメータの追加)強力なプラグインはユーザーがカスタマイズできるため、プラグインを作成する際にはより包括的に考慮し、適切なパラメータを提供するように努める必要があります。
比如:现在我们不想让链接只变成红色,我们让插件的使用者自己定义显示什么颜色,要做到这一点很方便,只需要使用者在调用的时候传入一个参数即可。同时我们在插件的代码里面接收。另一方面,为了灵活,使用者可以不传递参数,插件里面会给出参数的默认值。
在处理插件参数的接收上,通常使用jQuery的extend方法,上面也提到过,但那是给extend方法传递单个对象的情况下,这个对象会合并到jQuery身上,所以我们就可以在jQuery身上调用新合并对象里包含的方法了。
当给extend方法传递一个以上的参数时,它会将所有参数对象合并到第一个里。同时,如果对象中有同名属性时,合并的时候后面的会覆盖前面的。
利用这一点,我们可以在插件里定义一个保存插件参数默认值的对象,同时将接收来的参数对象合并到默认对象上,最后就实现了用户指定了值的参数使用指定的值,未指定的参数使用插件默认值。
为了演示方便,再指定一个参数fontSize,允许调用插件的时候设置字体大小。
$.fn.myPlugin = function(options) { var defaults = { 'color': 'red', 'fontSize': '12px' }; var settings = $.extend(defaults, options);//默认参数与用户设置的参数进行合并 return this.css({ 'color': settings.color, 'fontSize': settings.fontSize }); }
现在,我们调用的时候指定颜色,字体大小未指定,会运用插件里的默认值12px。
$('a').myPlugin({ 'color': '#2C9929' });
运行结果如下图:
保护好默认参数
注意到上面代码调用extend时会将defaults的值改变,这样不好,因为它作为插件因有的一些东西应该维持原样,另外就是如果你在后续代码中还要使用这些默认值的话,当你再次访问它时它已经被用户传进来的参数更改了。
保护好插件的默认参数
一个好的做法是将一个新的空对象做为$.extend的第一个参数,defaults和用户传递的参数对象紧随其后,这样做的好处是所有值被合并到这个空对象上,保护了插件里面的默认值。
$.fn.myPlugin = function(options) { var defaults = { 'color': 'red', 'fontSize': '12px' }; var settings = $.extend({},defaults, options);//将一个空对象做为第一个参数,后面的参数,全部合在一个对象里面。 return this.css({ 'color': settings.color, 'fontSize': settings.fontSize }); }
到此,插件可以接收和处理参数后,就可以编写出更健壮而灵活的插件了。若要编写一个复杂的插件,代码量会很大,如何组织代码就成了一个需要面临的问题,没有一个好的方式来组织这些代码,整体感觉会杂乱无章,同时也不好维护,所以将插件的所有方法属性包装到一个对象上,用面向对象的思维来进行开发,无疑会使工作轻松很多。
二、面向对象版本插件
为什么要有面向对象的思维,因为如果不这样,你可能需要一个方法的时候就去定义一个function,当需要另外一个方法的时候,再去随便定义一个function,同样,需要一个变量的时候,毫无规则地定义一些散落在代码各处的变量。
还是老问题,不方便维护,也不够清晰。当然,这些问题在代码规模较小时是体现不出来的。
如果将需要的重要变量定义到对象的属性上,函数变成对象的方法,当我们需要的时候通过对象来获取,一来方便管理,二来不会影响外部命名空间,因为所有这些变量名还有方法名都是在对象内部。
接着上面的例子,我们可以把这个插件抽象成一个美化页面的对象,因为他的功能是设置颜色啊字体啊什么的,当然我们还可以加入其他功能比如设置下划线啊什么的。当然对于这个例子抽象成对象有点小题大做,这里仅作演示用。
所以我们新建一个对象命名为Beautifier,然后我们在插件里使用这个对象来编码。
//定义Beautifier的构造函数 var Beautifier = function(ele, opt) { this.$element = ele, this.defaults = { 'color': 'red', 'fontSize': '12px', 'textDecoration':'none' }, this.options = $.extend({}, this.defaults, opt) } //定义Beautifier的方法Beautifier.prototype = { beautify: function() { return this.$element.css({ 'color': this.options.color, 'fontSize': this.options.fontSize, 'textDecoration': this.options.textDecoration }); }} //在插件中使用Beautifier对象 $.fn.myPlugin = function(options) { //创建Beautifier的实体 var beautifier = new Beautifier(this, options); //调用其方法 return beautifier.beautify(); }
通过上面这样一改造,我们的代码变得更面向对象了,也更好维护和理解,以后要加新功能新方法,只需向对象添加新变量及方法即可,然后在插件里实例化后即可调用新添加的东西。
插件的调用还是一样的,我们对代码的改动并不影响插件其他地方,只是将代码的组织结构改动了而以。
$(function() { $('a').myPlugin({ 'color': '#2C9929', 'fontSize': '20px' }); });
三、需要注意的几点
1、关于命名空间
不仅仅是jQuery插件的开发,我们在写任何JS代码时都应该注意的一点是不要污染全局命名空间。因为随着你代码的增多,如果有意无意在全局范围内定义一些变量的话,最后很难维护,也容易跟别人写的代码有冲突。
比如:你在代码中向全局window对象添加了一个变量status用于存放状态,同时页面中引用了另一个别人写的库,也向全局添加了这样一个同名变量,最后的结果肯定不是你想要的。所以不到万不得已,一般我们不会将变量定义成全局的。
一个好的做法是始终用自调用匿名函数包裹你的代码,这样就可以完全放心,安全地将它用于任何地方了,绝对没有冲突。
用自调用匿名函数包裹你的代码
我们知道JavaScript中无法用花括号方便地创建作用域,但函数却可以形成一个作用域,域内的代码是无法被外界访问的。如果我们将自己的代码放入一个函数中,那么就不会污染全局命名空间,同时不会和别的代码冲突。
如上面我们定义了一个Beautifier全局变量,它会被附到全局的window对象上,为了防止这种事情发生,你或许会说,把所有代码放到jQuery的插件定义代码里面去啊,也就是放到$.fn.myPlugin里面。这样做倒也是种选择。但会让我们实际跟插件定义有关的代码变得臃肿,而在$.fn.myPlugin里面我们其实应该更专注于插件的调用,以及如何与jQuery互动。
所以保持原来的代码不变,我们将所有代码用自调用匿名函数包裹。
(function() { //定义Beautifier的构造函数 var Beautifier = function(ele, opt) { this.$element = ele, this.defaults = { 'color': 'red', 'fontSize': '12px', 'textDecoration': 'none' }, this.options = $.extend({}, this.defaults, opt) } //定义Beautifier的方法 Beautifier.prototype = { beautify: function() { return this.$element.css({ 'color': this.options.color, 'fontSize': this.options.fontSize, 'textDecoration': this.options.textDecoration }); } } //在插件中使用Beautifier对象 $.fn.myPlugin = function(options) { //创建Beautifier的实体 var beautifier = new Beautifier(this, options); //调用其方法 return beautifier.beautify(); } })();
这样做的好处:也就是上面所阐述的那样。另外还有一个好处就是,自调用匿名函数里面的代码会在第一时间执行,页面准备好过后,上面的代码就将插件准备好了,以方便在后面的代码中使用插件。
目前为止似乎接近完美了,如果再考虑到其他一些因素。
比如:我们将这段代码放到页面后,前面别人写的代码没有用分号结尾,或者前面的代码将window, undefined等这些系统变量或者关键字修改掉了,正好我们又在自己的代码里面进行了使用,那结果也是不可预测的,这不是 我们想要的。我知道其实你还没太明白,下面详细介绍。
来看下面的代码,你猜他会出现什么结果?
var foo=function(){ //别人的代码 }//注意这里没有用分号结尾 //开始我们的代码。。。 (function(){ //我们的代码。。 alert('Hello!'); })();
本来别人的代码也正常工作,只是最后定义的那个函数没有用分号结尾而以,然后当页面中引入我们的插件时,报错了,我们的代码无法正常执行。
代码报错
原因是我们用来充当自调用匿名函数的第一对括号与上面别人定义的函数相连,因为中间没有分号嘛,总之我们的代码无法正常解析了,所以报错。
所以好的做法是我们在代码开头加一个分号,这在任何时候都是一个好的习惯。
var foo=function(){ //别人的代码 }//注意这里没有用分号结尾 //开始我们的代码。。。 ;(function(){ //我们的代码。。 alert('Hello!'); })();
同时,将系统变量以参数形式传递到插件内部也是个不错的实践。
当我们这样做之后,window等系统变量在插件内部就有了一个局部的引用,可以提高访问速度,会有些许性能的提升。
最后我们得到一个非常安全结构良好的代码:。
;(function($,window,document,undefined){ //我们的代码。。 })(jQuery,window,document);
而至于这个undefined,稍微有意思一点,为了得到没有被修改的undefined,我们并没有传递这个参数,但却在接收时接收了它,因为实际并没有传,所以‘undefined’那个位置接收到的就是真实的'undefined'了。是不是有点hack的味道,值得细细体会的技术,当然不是我发明的,都是从前人的经验中学习。
所以最后我们的插件成了这样:
;(function($, window, document,undefined) { //定义Beautifier的构造函数 var Beautifier = function(ele, opt) { this.$element = ele, this.defaults = { 'color': 'red', 'fontSize': '12px', 'textDecoration': 'none' }, this.options = $.extend({}, this.defaults, opt) } //定义Beautifier的方法 Beautifier.prototype = { beautify: function() { return this.$element.css({ 'color': this.options.color, 'fontSize': this.options.fontSize, 'textDecoration': this.options.textDecoration }); } } //在插件中使用Beautifier对象 $.fn.myPlugin = function(options) { //创建Beautifier的实体 var beautifier = new Beautifier(this, options); //调用其方法 return beautifier.beautify(); } })(jQuery, window, document);
一个安全,结构良好,组织有序的插件编写完成。
2、关于变量定义及命名
现在谈谈关于变量及方法等的命名,没有硬性规定,但为了规范,遵循一些约定还是很有必要的。
变量定义:好的做法是把将要使用的变量名用一个var关键字一并定义在代码开头,变量名间用逗号隔开。原因有两点:
一、是便于理解,知道下面的代码会用到哪些变量,同时代码显得整洁且有规律,也方便管理,变量定义与逻辑代码分开。
二、是因为JavaScript中所有变量及函数名会自动提升,也称之为JavaScript的Hoist特性,即使你将变量的定义穿插在逻辑代码中,在代码解析运行期间,这些变量的声明还是被提升到了当前作用域最顶端的,所以我们将变量定义在一个作用域的开头是更符合逻辑的一种做法。当然,再次说明这只是一种约定,不是必需的。
变量及函数命名:
(1)一般使用驼峰命名法(CamelCase),即首个单词的首字母小写,后面单词首字母大写。
比如:resultArray,requestAnimationFrame。
(2)对于常量,所有字母采用大写,多个单词用下划线隔开。
比如:WIDTH=100,BRUSH_COLOR='#00ff00'。
(3)当变量是jQuery类型时,建议以$开头,开始会不习惯,但经常用了之后会感觉很方便。
因为可以很方便地将它与普通变量区别开来,一看到以$开头我们就知道它是jQuery类型可以直接在其身上调用jQuery相关的方法。
比如:var $element=$('a'); 之后就可以在后面的代码中很方便地使用它,并且与其他变量容易区分开来。
引号的使用:既然都扯了这些与插件主题无关的了,这里再多说一句,一般HTML代码里面使用双引号,而在JavaScript中多用单引号,比如下面代码所示:
var name = 'Wayou';document.getElementById(‘example’); name.innerHTML = '< a href="http: //www.zymseo.com/">'+name+''; //href=".." HTML中保持双引号,JavaScript中保持单引号
一方面,HTML代码中本来就使用的是双引号,另一方面,在JavaScript中引号中还需要引号的时候,要求我们单双引号间隔着写才是合法的语句,除非你使用转意符("\")那也是可以的。再者,坚持这样的统一可以保持代码风格的一致,不会出现这里字符串用双引号包着,另外的地方就在用单引号。
以上がjQueryプラグインの開発手法にはどのようなものがあるのでしょうか? jQueryプラグインを開発する3つの方法のまとめ(推奨)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。