第8章 高效開發和使用外掛 (一)
jQuery 的流行在很大程度上歸功於其對外掛的支援。外掛也就是功能擴充套件的意思,jQuery 允許任何開發人員超越最初的庫函式建立並擴充套件 jQuery 函式。這種開放性框架設計思路催生了無數實用型的外掛,jQuery 幾乎能夠提供 Web 應用程式內所需的任何一種函式。
jQuery 的易擴充套件性吸引了越來越多的開發者和業餘愛好者去研究、設計和使用 jQuery 外掛。目前,全球有超過上千種不同應用需要的外掛。使用這些外掛能夠幫助開發人員提升開發速度,節約勞動成本。最權威的外掛可以訪問 jQuery 官方網站 (http://plugins.jquery.com) 獲取。本章將重點講解如何建立自己的 jQuery 外掛,並就網路上比較經典的幾個外掛設計原理和使用進行介紹。
8.1 建立 jQuery 外掛
網路上流傳著成百上千的第三方外掛,這些外掛雖然能夠增強我們的程式設計體驗,但是很難滿足所有設計需要,特別是個性化開發需求。如果自己編寫的程式碼可以重用,或者供其他使用者參考,很自然任何人都希望把這些程式碼進行封裝,打包為一個新外掛。這個實現過程並不困難,只要讀者認真閱讀本節內容即可輕鬆實現。
8.1.1 jQuery 外掛的型別
jQuery 外掛主要分為三種型別,說明如下。
1. jQuery 方法
這種型別的外掛是把一些常用或者重複使用的功能定義為函式,然後繫結到 jQuery 物件上,從而成為 jQuery 物件的一個擴充套件方法。
目前,大部分jQuery外掛都是這種型別的外掛,由於這種外掛是將物件方法封裝起來,在 jQuery 選擇器獲取 jQuery 物件的過程中進行操作,從而發揮 jQuery 強大的選擇器優勢。有很多 jQuery 內部方法,也是在 jQuery 指令碼內部通過這種形式插入到 jQuery 框架中的,如 parent() 、appendTo() 和 addClass() 等方法。
2.全域性函式
也可以把自定義的功能函式獨立附加到 jQuery 名稱空間下,從而作為 jQuery 作用域下的一個公共函式使用。例如,jQuery 的 ajax() 方法就是利用這種途徑內部定義的全域性函式。
==由於全域性函式沒有被繫結到 jQuery 物件上,故不能夠在選擇器獲取的 jQuery 物件上呼叫。需要通過 jQuery.fn() 或者 $.fn() 方式進行引用。==
3.選擇器
jQuery 提供了強大的選擇器,當然在個性化開發中,讀者也可能會感覺到這些選擇器不夠用,或者使用不是很方便。這個時候,我們就可以考慮自定義選擇器,以滿足特定環境下的選擇元素需要。
8.1.2 解析 jQuery 外掛機制
為了方便使用者建立外掛,jQuery 自定義了 jQuery.extend() 和 jQuery.fn.extend() 方法。其中 jQuery.extend() 方法能夠建立全域性函式或者選擇器,而 jQuery.fn.extend() 方法能夠建立 jQuery 物件方法。
例如,下面的示例將在 jQuery 名稱空間上建立兩個公共函式。
- <scripttype="text/javascript">
- jQuery.extend({//擴充套件jQuery的公共函式
- minValue:function(a,b){//比較兩個引數值,返回最小值
- returna<b?a:b;
- },
- maxValue:function(a,b){//比較兩個引數值,返回最大值
- returna<b?b:a;
- }
- });
- </script>
- <scripttype="text/javascript">
- jQuery.extend({//擴充套件jQuery的公共函式
- minValue:function(a,b){//比較兩個引數值,返回最小值
- returna<b?a:b;
- },
- maxValue:function(a,b){//比較兩個引數值,返回最大值
- returna<b?b:a;
- }
- });
- $(function(){
- $("input").click(function(){
- vara=prompt("請輸入一個數值?");
- varb=prompt("請再輸入一個數值?");
- varc=jQuery.minValue(a,b);
- vard=jQuery.maxValue(a,b);
- alert("你輸入的最大值是:"+d+"\n你輸入的最小值是:"+c);
- });
- });
- </script>
- </head>
- <body>
- <inputtype="button"value="jQuery外掛擴充套件測試"/>
- </body>
jQuery.extend() 和 jQuery.fn.extend() 方法都包含一個引數,該引數僅接受名/值對結構的物件,其中名錶示函式或方法名,而值表示函式體。關於如何建立 jQuery 外掛的問題,我們將在下面小節中進行詳細講解。
jQuery.extend() 方法除了可以建立外掛外,還可以用來擴充套件 jQuery 物件。例如,在下面的示例中,呼叫 jQuery.extend() 方法把物件 a 和 b 合併為一個新的物件,並返回合併物件將其賦值給變數 c 。
- <scripttype="text/javascript">
- vara={//物件直接量
- name:"zhu",
- pass:123
- };
- varb={//物件直接量
- name:"wang",
- pass:456,
- age:1
- };
- varc=jQuery.extend(a,b);//合併物件a和b
- $(function(){
- for(varnameinc){//遍歷物件c,顯示合併後的物件c的具體屬性和值
- $("div").html($("div").html()+"<br/>"+name+":"+c[name]);
- }
- });
- </script>
- </head>
- <body>
- <div></div>
- </body>
在實際開發中,常常使用 jQuery.extend() 方法為外掛方法傳遞系列選項結構的引數。
這樣當在呼叫該方法時,如果想傳遞新的引數值,就會覆蓋掉預設的引數選項值,或者向函式引數新增新的屬性和值;如果沒有傳遞引數,則保持並使用預設值。例如,在下面幾個函式呼叫中,分別傳入新值,或者新增新引數,或者保持預設值。
- <scripttype="text/javascript">
- functionfn(options){
- varoptions=jQuery.extend({//預設引數選項列表
- name1:value1,
- name2:value2,
- name3:value3,
- },options);//使用函式的引數覆蓋或合併到預設引數選項列表中
- //函式體
- }
- fn({name1:value2,name2:value3,name3:value1});//覆蓋新值
- fn({name4:value4,name5:value5});//新增新選項
- fn();//保持預設引數值
- </script>
jQuery.extend() 方法的物件合併機制,比傳統的逐個檢測引數不僅靈活且簡潔,使用命名引數新增新選項也不會影響已編寫的程式碼風格,讓程式碼變得更加直觀明白。
8.1.3 建立 jQuery 全域性函式
jQuery 內建的很多方法都是通過全域性函式實現的。所謂全域性函式,就是 jQuery 物件的方法,實際上就是位於 jQuery 名稱空間內部的函式。
有人把這類函式稱為實用工具函式,這些函式有一個共同特徵,就是不直接操作 DOM 元素,而是操作 JavaScript 的非元素物件,或者執行其他非物件的特定操作,如 jQuery 的 each() 函式和 noConflict() 函式。
回憶一下上一章講解過的 ajax() 方法,它就是一個典型的 jQuery 全域性函式,$.ajax() 所做的一切都可以通過呼叫名稱為 ajax() 的全域性函式來實現。但是,這種方式會帶來函式衝突問題,如果把函式放置在 jQuery 名稱空間內,就會降低這種衝突,只要在 jQuery 名稱空間內注意不要與 jQuery 其他方法衝突即可。
在上一節中曾經介紹了使用 jQuery.extend() 方法可以擴充套件 jQuery 物件的全域性函式。當然,我們也可以使用下面的方法快速定義 jQuery 全域性函式。例如,針對上一節示例,我們也可以按如下方法進行編寫。
- <scripttype="text/javascript">
- jQuery.minValue=function(a,b){
- returna<b?a:b;
- };
- jQuery.maxValue=function(a,b){
- returna<b?b:a;
- };
- </script>
考慮到 jQuery 的外掛越來越多,因此在使用時可能會遇到自己的外掛與第三方外掛名發生衝突的問題。為了避免這個問題,建議把屬於自己的外掛都封裝在一個物件中。例如,針對上面兩個建立的全域性函式,可以把它們封裝在自己的物件中,實現程式碼如下。
- <scripttype="text/javascript">
- jQuery.css8={
- minValue:function(a,b){
- returna<b?a:b;
- },
- maxValue:function(a,b){
- returna<b?b:b;
- }
- };
- </script>
- varc=jQuery.css8.minValue(a,b);
- vard=jQuery.css8.maxValue(a,b);
8.1.4 使用 jQuery.fn 物件建立 jQuery 物件方法
除了全域性函式外,jQuery 中的大多數功能都是通過 jQuery 物件的方法提供的,這些物件方法對於 DOM 操作來說非常方便,這也是很多使用者喜歡並選用 jQuery 框架的原因。
建立全域性函式只需要通過為 jQuery 物件新增屬性即可,而建立 jQuery 物件方法也可以通過為 jQuery.fn 物件新增屬性來實現。實際上 jQuery.fn 物件就是 jQuery.prototype 原型物件的別名,使用別名更方便引用。例如,下面這個函式就是一個簡單的 jQuery 物件方法,當呼叫該方法時,將會彈出一個提示對話方塊。
- <scripttype="text/javascript">
- jQuery.fn.test=function(){
- alert('這是jQuery物件方法!');
- };
- </script>
- <scripttype="text/javascript">
- jQuery.fn.test=function(){
- alert('這是jQuery物件方法!');
- };
- $(function(){
- $("input").click(function(){//繫結click事件
- $(this).test();//在當前的jQuery物件上呼叫test()方法
- });
- });
- </script>
- </head>
- <body>
- <inputtype="button"value="jQuery外掛擴充套件測試"/>
- </body>
由於這裡並沒有在任何地方匹配 DOM 節點,所以編寫全域性函式也是可以的。但是,在使用 jQuery 物件方法時,函式體內的 this 關鍵字總是引用當前 jQuery 物件,因此我們可以對上面的方法進行重寫,實現動態提示資訊。程式碼如下。
- <scripttype="text/javascript">
- jQuery.fn.test=function(){
- alert(this[0].nodeName);//提示當前jQuery物件的DOM節點名稱
- };
- $(function(){
- $("input").click(function(){//繫結click事件
- $(this).test();//在當前的jQuery物件上呼叫test()方法
- });
- });
- </script>
- </head>
- <body>
- <inputtype="button"value="jQuery外掛擴充套件測試"/>
- </body>
這樣,當單擊按鈕時,就會彈出當前元素的節點名稱。
在上面的示例中,可以看到由於 jQuery 選擇器返回的是一個陣列型別的 DOM 節點集合,this 指標就指向當前這個集合,故要顯示當前元素的節點名稱,就必須在 this 指標後面指定當前元素的序號。
試想,如果 jQuery 選擇器匹配多個元素,我們該如何準確指定當前元素物件呢?
要解決這個問題,我們不妨在當前 jQuery 物件方法的環境中呼叫 each() 方法,通過隱式迭代的方式,讓 this 指標依次引用每一個匹配的 DOM 元素物件。這樣也能夠保持外掛與 jQuery 內建方法保持一致。例如,針對上面的示例做進一步的修改。
- jQuery.fn.test=function(){
- this.each(function(){//遍歷所有匹配的元素,此處的this表示物件集合,即jQuery物件
- alert(this.nodeName);//顯示當前元素的節點名稱,此處的this表示元素物件
- });
- };
- <scripttype="text/javascript">
- jQuery.fn.test=function(){
- this.each(function(){//遍歷所有匹配的元素,此處的this表示物件集合,即jQuery物件
- alert(this.nodeName);//顯示當前元素的節點名稱,此處的this表示元素物件
- });
- };
- $(function(){
- $("body*").click(function(){//選擇body元素下所有元素
- $(this).test();//為當前元素呼叫test()方法,提示當前DOM元素物件的節點名稱
- });
- });
- </script>
- </head>
- <body>
- <inputtype="button"value="jQuery外掛擴充套件測試"/>
- <div>div元素</div>
- <p>p元素</p>
- <span>span元素</span>
- </body>
用慣 jQuery 的使用者可能習慣於連寫行為,也就是說在呼叫一個方法之後,緊跟著呼叫另一個方法,如此連寫不斷,形成一個珍珠鏈,而且編寫靈活、方便,也符號人的思維習慣。例如
$(this).test().hide().height();
要實現類似的行為連寫功能,就應該在每個外掛方法中返回一個 jQuery 物件,除非方法需要明確返回值。返回的 jQuery 物件通常就是 this 所引用的物件。如果使用 each() 方法迭代 this ,則可以直接返回迭代的結果。例如,針對上面的示例做如下進一步的修改。
- jQuery.fn.test=function(){
- returnthis.each(function(){//返回迭代的jQuery物件
- alert(this.nodeName);
- });
- };
- <scripttype="text/javascript">
- jQuery.fn.test=function(){
- returnthis.each(function(){//返回迭代的jQuery物件
- alert(this.nodeName);
- });
- };
- $(function(){
- $("body*").click(function(){//選擇body元素下所有元素
- $(this).test().html(this.nodeName).hide(4000);//行為連寫
- });
- });
- </script>
- </head>
- <body>
- <inputtype="button"value="jQuery外掛擴充套件測試"/>
- <div>div元素</div>
- <p>p元素</p>
- <span>span元素</span>
- </body>
8.1.5 使用 extend() 方法建立 jQuery 物件方法
jQuery.extend() 方法能夠建立全域性函式,而 jQuery.fn.extend() 方法可以建立 jQuery 物件方法。如果讀者明白了上一節使用 jQuery.fn 物件屬性的方法建立 jQuery 物件方法,那麼使用 extend() 方法建立 jQuery 物件就比較容易理解了。
例如,針對上節中介紹的示例,我們可以呼叫 jQuery.fn.extend() 方法來建立 jQuery 物件方法。具體程式碼如下。
- jQuery.fn.extend({
- test:function(){
- returnthis.each(function(){
- alert(this.nodeName);
- });
- }
- });
針對上面定義的 test() 方法,同樣可以在 jQuery 選擇器中直接呼叫。
- <scripttype="text/javascript">
- jQuery.fn.extend({
- test:function(){
- returnthis.each(function(){
- alert(this.nodeName);
- });
- }
- });
- $(function(){
- $("body*").click(function(){//選擇body元素下所有元素
- $(this).test().html(this.nodeName).hide(4000);//行為連寫
- });
- });
- </script>
- </head>
- <body>
- <inputtype="button"value="jQuery外掛擴充套件測試"/>
- <div>div元素</div>
- <p>p元素</p>
- <span>span元素</span>
- </body>
相關文章
- 第8章 高效開發和使用外掛 (二)
- 第8章 高效開發和使用外掛 (三)
- 小程式外掛的開發和使用
- Java高效開發-常用idea外掛JavaIdea
- Vue如何使用混合Mixins和外掛開發Vue
- 使用pgrx開發postgre外掛
- Eclipse外掛開發(原書第3版)Eclipse
- 用於前端開發的十種高效Chrome外掛前端Chrome
- 使用 Java 開發 Gradle 外掛JavaGradle
- 使用Python開發Chrome外掛PythonChrome
- Android Studio Plugin 外掛開發教程(一) —— 開發你的第一個外掛AndroidPlugin
- 如何開發一個 PyCharm 外掛PyCharm
- Android外掛式開發(一)Android
- 從頭開發一個Flutter外掛(一)開發流程Flutter
- VSCode 必裝的 10 個高效開發外掛VSCode
- 高效率開發的Android Studio外掛收集Android
- 使用React.js開發Chrome外掛ReactJSChrome
- chrome外掛開發簡介(一)——開發入門Chrome
- Flutter外掛開發Flutter
- Mybatis外掛開發MyBatis
- Webstorm 外掛開發WebORM
- flutter 外掛開發Flutter
- 開發Rhino外掛
- chrome 外掛開發Chrome
- vue開發的一些外掛Vue
- SDK 開發使用 VirtualAPK 實現外掛化APK
- 從頭開發一個Flutter外掛(二)高德地圖定位外掛Flutter地圖
- apisix~lua外掛開發與外掛註冊API
- HtmlWebpackPlugin外掛和HtmlWebpackInlineSourcePlugin外掛的使用HTMLWebPlugininline
- 使用js開發一個快速開啟前端專案的alfred外掛JS前端Alfred
- [外掛推薦] 使用 PHPStorm 中的 Laravel Plugin 外掛提升開發效率PHPORMLaravelPlugin
- fastclick外掛的使用--移動端vue專案開發(vue常用外掛)ASTVue
- 外掛化開發筆記(一)代理模式筆記模式
- Grafana的Datasource外掛開發實踐一Grafana
- 開發了一個 JATO for JBuilder 的外掛UI
- babel 外掛開發案例Babel
- Maven外掛開發教程Maven
- Chrome外掛開發教程Chrome