今日は、既存のタブ切り替え機能を JavaScript プラグインに書き換える、最も単純な方法から始めましょう。
ネイティブ関数の書き方
JavaScript メソッドを JS プラグインとして書き直す最も簡単な方法は、このメソッドをウィンドウ グローバル オブジェクトの下にマウントすることです
まず、関数を使用して作成された最も独創的なコードを見てみましょう:
tab.html
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="renderer" content="webkit"> <title>jquery_hjb_tab插件demo</title> <link rel="stylesheet" href="h.css"/> </head> <body> <div id="tab"> <div class="tabs"> <ul> <li><a href="#">tab1</a></li> <li><a href="#">tab2</a></li> <li><a href="#">tab3</a></li> <li><a href="#">tab4</a></li> </ul> </div> <div class="tabCons"> <section>内容一</section> <section>内容二</section> <section>内容三</section> <section>内容四</section> </div> </div> <script> window.onload = h_tab('tab'); function h_tab(tabId){ var oLinks = document.getElementById(tabId).getElementsByTagName("a"); var oCons = document.getElementById(tabId).getElementsByTagName("section"); for(var i = 0; i<oLinks.length; i++){ oLinks[i].index = i; oLinks[i].onclick = function () { for(var j =0; j<oLinks.length; j++){ oLinks[j].className=""; oCons[j].style.display = "none"; } this.className="cur"; oCons[this.index].style.display ="block"; } } } </script>
h.css
@charset "utf-8"; /* //author:hjb2722404 //description: //date:2016/2/18 */ .tabs ul { width: 100%; list-style-type: none;} .tabs ul li { width: 48%; display: inline-block; margin: 0; padding: 0;} .tabs ul li a {border-bottom: 3px solid #cccccc; width: 100%; height: 100%; display: block; text-align: center; min-height: 40px; line-height: 40px; text-decoration: none; font-family: "微软雅黑"; color: #a94442} .tabs ul li a.cur { border-bottom: 3px solid #f26123;} .tabCons section { display: none;} .tabCons section:nth-child(1) { display: block;}
上記の 2 つのコードは基本的なコードであり、これをベースに段階的に改良していきます。
ネイティブプラグインの記述方法
さて、このメソッドをウィンドウ オブジェクトの下にマウントされたプラグインに書き換えましょう:
tab.html
…… // 下面是第一次改动 <script type="text/javascript" src="h_tabs.js"></script> <script> H_tab("tab"); </script> </body> </html>
h_tabs.js
window.H_tab = function(tabId){ var oLinks = document.getElementById(tabId).getElementsByTagName("a"); var oCons = document.getElementById(tabId).getElementsByTagName("section"); for(var i = 0; i<oLinks.length; i++){ oLinks[i].index = i; oLinks[i].onclick = function () { for(var j =0; j<oLinks.length; j++){ oLinks[j].className=""; oCons[j].style.display = "none"; } this.className="cur"; oCons[this.index].style.display ="block"; } } };
しかし、この書き方は非常に簡単ですが、問題もあることに気付きました。ウィンドウがグローバル オブジェクトであるため、その下にすべてのメソッドをマウントし、プラグインとして使用すると、メソッドが多すぎる場合に発生します。一方、ネイティブ js を使用すると、外部依存を減らすことができますが、コード量が比較的多く、記述方法も比較的面倒です。
jqueryの書き方
jquery ライブラリを導入し、このプラグインを jquery プラグインに書き換えてみます。
jquery プラグインには、クラスレベルの形式、オブジェクトレベルの形式、jquery UI コンポーネント形式の 3 つの形式があります
jquery クラスレベルのプラグインを作成する方法 – 単一メソッド
まずクラスレベルのプラグインの形式を見てみましょう。
最初のカテゴリレベルのプラグインの形式では、このメソッドはツール メソッドとして jquery のルート領域に直接マウントされます。
tab.html
…… <script src="../jquery.js" type="text/javascript"></script> <script type="text/javascript" src="h_tabs.js"></script> <script> $.h_tab('tab'); </script> </body> </html>
h_tabs.js
$.h_tab = function(tabId){ var oLinks = document.getElementById(tabId).getElementsByTagName("a"); var oCons = document.getElementById(tabId).getElementsByTagName("section"); for(var i = 0; i<oLinks.length; i++){ oLinks[i].index = i; oLinks[i].onclick = function () { for(var j =0; j<oLinks.length; j++){ oLinks[j].className=""; oCons[j].style.display = "none"; } this.className="cur"; oCons[this.index].style.display ="block"; } } };
jquery クラスレベルのプラグインの作成方法 - 複数のメソッド
複数のメソッドを jquery ルート空間にバインドしたい場合は、次のように記述します:
tab.html
…… <script src="../jquery.js" type="text/javascript"></script> <script type="text/javascript" src="h_tabs.js"></script> <script> $.h_tab('tab'); $.h_hello('hjb'); </script> </body> </html>
h_tabs.js
$.extend({ h_tab:function(tabId){ var oLinks = document.getElementById(tabId).getElementsByTagName("a"); var oCons = document.getElementById(tabId).getElementsByTagName("section"); for(var i = 0; i<oLinks.length; i++){ oLinks[i].index = i; oLinks[i].onclick = function () { for(var j =0; j<oLinks.length; j++){ oLinks[j].className=""; oCons[j].style.display = "none"; } this.className="cur"; oCons[this.index].style.display ="block"; } } }, h_hello :function(name){ console.log("hello,",name); } });
$.extend() ツール メソッドを使用して独自の関数を jquery ルート名前空間に直接マウントするのは簡単で問題はありませんが、残念ながら、この方法では jquery の強力なシズル エンジンを利用できません。メソッドは、選択した DOM 要素に適用できません。
したがって、オブジェクトレベルのプラグイン開発方法を使用する必要があります。
jquery オブジェクトレベルプラグインの書き方
オブジェクトレベルのプラグイン開発方法では、$.fn.extend() メソッドを使用して独自のメソッドを jquery プロトタイプにバインドし、すべての jquery オブジェクト チームがこのメソッドを適用して対応する操作を実行できるようにします
コードは次のとおりです:
tab.html
…… <script src="../jquery.js" type="text/javascript"></script> <script type="text/javascript" src="h_tabs.js"></script> <script> //对象级别的插件引用方法,注意和上面类级别插件的写法上的区分 $('#tab').h_tab('tab'); </script> </body> </html>
h_tabs.js
(function($){ $.fn.extend({ h_tab:function(tabId){ var oLinks = document.getElementById(tabId).getElementsByTagName('a'); var oCons = document.getElementById(tabId).getElementsByTagName('section'); for(var i = 0; i<oLinks.length; i++){ oLinks[i].index = i; oLinks[i].onclick = function () { for(var j =0; j<oLinks.length; j++){ oLinks[j].className=""; oCons[j].style.display = "none"; } this.className="cur"; oCons[this.index].style.display ="block"; } } } }); })(jQuery);
ここでは、名前空間の汚染を避けるためにクロージャを使用してプラグインをカプセル化します
ここにはまだいくつかの問題があります。つまり、メソッドを実行する前にパラメーターを渡す必要があるため、呼び出し時に $('#tab') を使用してタブの ID を持つ div を選択する必要があります。次に、プラグインでは、渡された ID に基づいて要素が再度取得されます。
jquery のセレクターを使用したので、これを導入して要素を繰り返し取得するという冗長な問題を解決できます。
jqueryオブジェクトレベルのプラグインの書き方 - これを紹介します
tab.html
…… <script src="../jquery.js" type="text/javascript"></script> <script type="text/javascript" src="h_tabs.js"></script> <script> $('#tab').h_tab(); </script> </body> </html>
h_tabs.js
(function($){ $.fn.extend({ h_tab:function(){ //在这里引入this var oLinks = this.find('a'); var oCons = this.find('section'); for(var i = 0; i<oLinks.length; i++){ oLinks[i].index = i; oLinks[i].onclick = function () { for(var j =0; j<oLinks.length; j++){ oLinks[j].className=""; oCons[j].style.display = "none"; } this.className="cur"; oCons[this.index].style.display ="block"; } } } }); })(jQuery);
ここで注意する必要があるのは、プラグインと呼ぶ要素オブジェクトは ('tab') であるため、この時点で this.find() を直接使用することは ('tab').find() と同等であるということです。 $(this).find() ではなく、置換メソッドを使用して 2 つの記述メソッドの違いを区別することに注意してください。
プラグインとして、開発者が制御できる必要があるため、ユーザーにいくつかの構成インターフェイスも提供する必要があります。
jqueryオブジェクトレベルのプラグイン記述方法 - 設定項目の追加
tab.html
…… <ul> <!--对照文章开始的代码, 注意这里的改动 --> <li><a href="#" class="current">tab1</a></li> <li><a href="#">tab2</a></li> …… <script src="../jquery.js" type="text/javascript"></script> <script type="text/javascript" src="h_tabs.js"></script> <script> $('#tab').h_tab({ //使得当前选项卡标签的样式名称可自定义的配置 curName:'current' }); </script> </body> </html>
初期の「現在のタブラベルスタイルクラス名」を「cur」から「current」に変更し、設定項目としてプラグインに渡しました
h.css
.tabs ul { width: 100%; list-style-type: none;} .tabs ul li { width: 48%; display: inline-block; margin: 0; padding: 0;} .tabs ul li a {border-bottom: 3px solid #cccccc; width: 100%; height: 100%; display: block; text-align: center; min-height: 40px; line-height: 40px; text-decoration: none; font-family: "微软雅黑"; color: #a94442} /*注意下面一行与之前的样式代码的对比变化之处*/ .tabs ul li a.current { border-bottom: 3px solid #f26123;} .tabCons section { display: none;} .tabCons section:nth-child(1) { display: block;}
スタイルシートにも対応する変更を加えました。
h_tabs.js
(function($){ $.fn.extend({ //给方法传入一个对象作为参数 h_tab:function(opts){ //定义默认的配置 var defaults ={ curName : 'cur' }; //将传入的参数覆盖默认参数中的默认项,最终合并到一个新的参数对象上 var Opt = $.extend({},defaults,opts); var oLinks = this.find('a'); var oCons = this.find('section'); for(var i = 0; i<oLinks.length; i++){ oLinks[i].index = i; oLinks[i].onclick = function () { for(var j =0; j<oLinks.length; j++){ oLinks[j].className=""; oCons[j].style.display = "none"; } //在这里使用配置项的值 this.className = Opt['curName']; oCons[this.index].style.display ="block"; } } } }); })(jQuery);
ここでは、jquery の $.extend() メソッドのオブジェクトのマージ関数を使用して、デフォルトの構成項目をユーザーが渡した構成項目で上書きし、最終的にそれらを後続のプログラムで使用できる新しい構成項目にマージします。
上記は編集者が紹介したJavaScriptタブプラグインのサンプルコードですので、皆様のお役に立てれば幸いです。