從零開始寫一款javascript外掛程式(一)——tab選項卡
上一次寫了《從零開始學習製作H5情境應用》系列,反響還算好,所以趁最近不是太忙,繼續新的系列,從零開始寫javascript外掛程式。
今天,先從最簡單的開始,將已有的一個Tab選項卡切換功能改寫成javascript外掛程式形式。
原生函數寫法
將一個javascript方法改寫為js外掛程式最簡單的方式就是將這個方法掛載到window全域對象下面
我們先來看看最原始的使用函數寫法的代碼:
tab.html
<code class="language-html hljs "></code>
內容一
內容二
內容三
內容四
<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; ih.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;}
上面兩份代碼為基本代碼,之後我們後一步步在這份代碼的基礎上進行改進。
原生外掛程式寫法好,現在,我們就來將這個方法改寫成掛載在window對象下的外掛程式:
tab.html
<code class="language-html hljs "> ……// 下面是第一次改動<!--{cke_protected}%3Cscript%20type%3D%22text%2Fjavascript%22%20src%3D%22h_tabs.js%22%3E%3C%2Fscript%3E--><!--{cke_protected}%3Cscript%3E%0A%20%20%20%20H_tab(%22tab%22)%3B%0A%3C%2Fscript%3E--></code>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
但是,我們發現這樣的寫法雖然很簡單,但也有問題:window作為一個全域對象,如果我們把自己的方法都掛載到它下面作為外掛程式使用的話,外掛程式一多,就容易產生命名空間衝突,另一方面,使用原生js雖然可以減少對外部的依賴,但代碼量相對還是很大,寫法比較繁瑣。
jquery寫法我們嘗試引入jquery庫,將此外掛程式改寫為jquery外掛程式。
jquery外掛程式有三種形式:類層級的形式,對象層級的形式,jquery UI組件的形式
jquery 類層級外掛程式寫法–單個方法我們先來看類層級外掛程式的形式。
第一種類層級外掛程式的形式,直接把該方法掛載到jquery的根空間下,作為一個工具方法:
tab.html
<code class="language-javascript hljs "><code class="language-html hljs ">……<!--{cke_protected}%3Cscript%20src%3D%22..%2Fjquery.js%22%20type%3D%22text%2Fjavascript%22%3E%3C%2Fscript%3E--><!--{cke_protected}%3Cscript%20type%3D%22text%2Fjavascript%22%20src%3D%22h_tabs.js%22%3E%3C%2Fscript%3E--><!--{cke_protected}%3Cscript%3E%0A%20%20%20%20%24.h_tab('tab')%3B%0A%3C%2Fscript%3E--></code></code>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
jquery類層級外掛程式寫法-多個方法如果你想要將多個方法綁定到jquery根空間上面,那麼像下面這樣寫:
tab.html
<code class="language-javascript hljs "><code class="language-javascript hljs "><code class="language-html hljs ">……<!--{cke_protected}%3Cscript%20src%3D%22..%2Fjquery.js%22%20type%3D%22text%2Fjavascript%22%3E%3C%2Fscript%3E--><!--{cke_protected}%3Cscript%20type%3D%22text%2Fjavascript%22%20src%3D%22h_tabs.js%22%3E%3C%2Fscript%3E--><!--{cke_protected}%3Cscript%3E%0A%20%20%20%20%24.h_tab('tab')%3B%0A%20%20%20%20%24.h_hello('hjb')%3B%0A%3C%2Fscript%3E--></code></code></code>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
雖然使用$.extend()工具方法將自己的功能函數直接掛載到jquery根命名空間下,簡單,省事兒,但很不幸的是,這樣的方式不能利用jquery強大的sizzle引擎,即你選擇到的DOM元素無法運用這個方法。
所以我們要用到對象層級的外掛程式開發方式。
jquery對象層級外掛程式寫法對象層級的外掛程式開發方式是利用$.fn.extend()方法將自己的方法綁定到jquery原型上去,這樣所有jquery對象隊可以應用該方法來執行相應操作了
代碼如下:
tab.html
<code class="language-javascript hljs "><code class="language-javascript hljs "><code class="language-javascript hljs "><code class="language-html hljs ">……<!--{cke_protected}%3Cscript%20src%3D%22..%2Fjquery.js%22%20type%3D%22text%2Fjavascript%22%3E%3C%2Fscript%3E--><!--{cke_protected}%3Cscript%20type%3D%22text%2Fjavascript%22%20src%3D%22h_tabs.js%22%3E%3C%2Fscript%3E--><!--{cke_protected}%3Cscript%3E%0A%20%20%20%20%2F%2F%E5%AF%B9%E8%B1%A1%E7%BA%A7%E5%88%AB%E7%9A%84%E6%8F%92%E4%BB%B6%E5%BC%95%E7%94%A8%E6%96%B9%E6%B3%95%EF%BC%8C%E6%B3%A8%E6%84%8F%E5%92%8C%E4%B8%8A%E9%9D%A2%E7%B1%BB%E7%BA%A7%E5%88%AB%E6%8F%92%E4%BB%B6%E7%9A%84%E5%86%99%E6%B3%95%E4%B8%8A%E7%9A%84%E5%8C%BA%E5%88%86%0A%20%20%20%20%24('%23tab').h_tab('tab')%3B%0A%3C%2Fscript%3E--></code></code></code></code>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
這裡,我們利用一個閉包封裝了外掛程式,避免了命名空間汙染
在這裡,還有一些問題,就是我們的方法必須傳參數才可以運行,這就導致調用的時候我們使用$(‘#tab’)選擇了id為tab的div,然後在外掛程式裡我們又根據傳入的ID擷取了一遍該元素。
既然我們已經使用了jquery的選取器,那麼我們就可以引入this來解決重複擷取元素的冗餘問題。
jquery對象層級外掛程式寫法-引入this
tab.html
<code class="language-javascript hljs "><code class="language-javascript hljs "><code class="language-javascript hljs "><code class="language-javascript hljs "><code class="language-html hljs ">……<!--{cke_protected}%3Cscript%20src%3D%22..%2Fjquery.js%22%20type%3D%22text%2Fjavascript%22%3E%3C%2Fscript%3E--><!--{cke_protected}%3Cscript%20type%3D%22text%2Fjavascript%22%20src%3D%22h_tabs.js%22%3E%3C%2Fscript%3E--><!--{cke_protected}%3Cscript%3E%0A%20%20%20%20%24('%23tab').h_tab()%3B%0A%3C%2Fscript%3E--></code></code></code></code></code>
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
這裡需要注意的是,我們調用該外掛程式的元素對象是(′tab′),則此時直接使用this.find()就等價於(‘tab’).find(),而不是$(this).find(),注意使用代入法來區分這兩種寫法的差別。
作為一款外掛程式,它應該是可以被開發人員控制的,所以還應該提供給使用者一些配置介面。
jquery對象層級外掛程式寫法-加入配置項
tab.html
<code class="language-javascript hljs "><code class="language-javascript hljs "><code class="language-javascript hljs "><code class="language-javascript hljs "><code class="language-javascript hljs "><code class="language-html hljs "> …… </code></code></code></code></code></code>
tab1
tab2
…… <script src="../jquery.js" type="text/javascript"></script><script type="text/javascript" src="h_tabs.js"></script><script> $('#tab').h_tab({ //使得當前選項卡標籤的樣式名稱可自訂的配置 curName:'current' });</script>
我們這裡把一開始的”當前選項卡標籤樣式類名稱“由”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
在這裡我們使用了jquery的$.extend()方法的合并對象的功能,使用使用者傳入的配置項覆蓋預設配置項並最終合并到一個新的配置項供後面的程式使用。
好了,經過了這麼幾步,我們基本上完成了一款最簡單的javascript外掛程式。所有代碼已經上傳至我的github上面,下面是地址:
git代碼倉庫查看源碼