JQuery外掛之$.fn
jQuery物件方法
$("a").css("color", "red");
當使用$
選擇元素的時候,它會返回一個jQuery物件,這個物件中包含了你一直使用的方法(比如:.css(),.click()等)。這個jQuery物件是從$.fn
物件中得到的這些方法。$.fn
物件包含了jQuery物件的所有方法,如果想編寫我們自己的方法,也要將方法定義在$.fn
物件裡面。使用這種方式編寫外掛,即jQuery類的例項
將會擁有此功能。為什麼會有這種效果?簡單看下原始碼
jQuery.fn = jQuery.prototype ={ init: function( selector, context ){ //do something... };
從原始碼可知,當使用$.fn
的方式編寫外掛時,就是在jQuery的原型中繫結新的方法,斯所以根據原型的特性,新建立的jQuery物件自然會擁有新繫結的方法。
初識外掛
目的:改變a標籤的字型顏色
做法:建立名為greenify
的方法,將其加在$.fn
裡面。
如此一來,greenify
方法適用於所有的jQuery物件了
<html> <head> <title>Title</title> <script type="text/javascript" src="../../js/jQuery-1.8.0.min.js"></script> <script type="text/javascript"> //這裡使用$與jQuery都可以 $.fn.greenify = function () { /*這裡使用this和$(this)都可以*/ this.css("color", "red"); }; $(function () { //$("a")即jQuery例項化物件 $("a").greenify(); }); </script> </head> <body> <a href="#">Click Me!!!</a> <a href="#">Cover Me!!!</a> </body> </html>
$.fn
還有另外一種寫法$.fn.extend({})
jQuery.fn.extend({ greenify: function () { $(this).css("color", "red"); } }); $(function () { $("a").greenify(); });
鏈式寫法
jQuery.fn.extend({ greenify: function () { $(this).css("color", "red"); //在結尾處返回this return this; } }); $(function () { $("a").greenify().addClass("greenified"); });
鏈式程式設計的好處就是當呼叫完一個方法後,可以在後面繼續呼叫該物件的其他方法。
$的別名保護
$
在JavaScript庫中使用是非常廣泛的,如果你正在使用的其他JavaScript類庫中也使用到了$
,並且你也使用了jQuery,那麼你不得不使用jQuery.noConflict()
來解除衝突。顯然這會破壞我們的外掛,因為它是在假設$
是jQuery函式的別名(實際上$
本來就是jQuery的別名)如果既想使用其他外掛,也要使用jQuery的$
別名,我們需要將程式碼放進立即執行函式
(文章結尾會對其簡單解釋)中,然後將jQuery作為實參傳遞進去,$
作為形參接收。
(function ( $ ) { $.fn.greenify = function() { this.css( "color", "green" ); return this; }; }( jQuery ));
由於window
,document
都是全域性作用域的,而將其傳入函式內部後,其在內部是作為區域性變數存在的,這樣做可以提高效能,減少作用域的查詢時間,如果在函式內部多次呼叫window
、document
,這是很高效的做法。
(function ( _window, _document ) { $.fn.greenify = function() { this.css( "color", "green" ); return this; }; }( window, document));
另外,儲存私有變數也是使用立即執行函式的主要目的,假如想要儲存一個預設的顏色,就可以使用一個私有變數進行儲存。
(function ($) { var defaultColor = "pink"; $.fn.extend({ setColor:function () { $(this).css("color", defaultColor); return $(this); } }) })(jQuery); $(function () { //所有div的text都會變成粉色 $("div").setColor(); });
;分號的使用
通常在編寫外掛時,會在在立即執行函式前加入一個分號
;(function($){ //do something... })(jQuery);
作用:防止多個檔案壓縮合並後,前一個檔案最後一行語句沒加分號,而引起合併後的語法錯誤。
如果前面已經加了分號,此時就會多出來一個分號,但這樣是不會報錯的。即不怕多,就怕少。
undefined解決相容性問題
;(function($, undefined){ //do something... })(jQuery)
上面程式碼的undefined
引數略顯多餘,此引數是為了解決undefined
在老一輩的瀏覽器(IE5)可以被賦值的問題,全域性的undefined有可能會被其他函式覆蓋。
var undefined = 99; alert(undefined);
以上程式碼如果在IE5
執行,可以彈出99, 而不是undefined
,如果是這樣的話,全域性的undefined
就有被其他函式覆蓋的危險;但以上程式碼在chrome
執行,會彈出undefined
。
既然是外掛就要考慮相容性,所以通過在匿名函式中多定義一個undefined
的形參,由於只傳入了一個實參jQuery
,從而可以保證undefined
形參未被賦值,從而最終是我們想要的undefined
的值,什麼是我們想要的undefined
?即,undefined
沒有被賦值,undefined
就是undefined
。
最大限度的減少外掛的空間
當使用$.fn
建立外掛時,儘量減少空間的佔用,能使用引數進行區分的,就不要多定義一個方法,這樣可以降低外掛被覆蓋的可能性。
- 反例
(function( $ ) { $.fn.TurnOnLight= function() { // Turn on }; $.fn.TurnOffLight = function() { // Turn off }; }( jQuery ));
- 正例
(function( $ ) { $.fn.light = function( action ) { if ( action === "turnOn") { // Turn on light code. } if ( action === "turnOff" ) { // Turn off light code. } }; }( jQuery ));
使用引數選項
當外掛越來越複雜時,通過接收引數選項的方式來自定義外掛是一種很好的做法。
<html> <head> <title>Title</title> <script type="text/javascript" src="../../js/jquery-1.8.0.min.js"></script> <script type="text/javascript"> (function ($) { $.fn.extend({ changeColor:function (options) { var defaultColor = $.extend({ color: "red", backgroundColor:"skyblue" }, options); return $(this).css({ color:defaultColor.color, backgroundColor:defaultColor.backgroundColor }); } }); })(jQuery); $(function () { $("div").changeColor(); /*$("div").changeColor({ color:"pink", backgroundColor:"yellow" });*/ }); </script> </head> <body> <div>JavaScript</div> <div>Jquery</div> </body> </html>
呼叫changeColor
不傳遞任何引數,文字顏色預設紅色,背景預設天藍色;反之按照傳入引數渲染顏色。預設的顏色被$.extned()
覆蓋為其他顏色。
$.extend({ color: "red", backgroundColor:"skyblue" }, options)
以上程式碼執行結果:options
如果有值,那麼它將覆蓋第一個引數並返回options;如果為undefined
則直接返回第一個引數。
簡單解釋立即執行函式(IIFE)
立即執行函式((Immediately-Invoked Function Expression)也稱為自呼叫函式,函式定義好後會自動執行。(function(){})
表示一個匿名函式,後面緊跟一個()
,表示立即執行函式。
(function(){ console.log("我會立即執行"); })() (function(param){ console.log(param); //我會立刻執行 })("我會立刻執行");
優點:不會產生產生全域性變數,不會造成變數汙染。
缺點:只能執行一次,沒法重複執行。
在編寫外掛時,使用IIFE 是最合適不過的了,外掛只需要引用一次,即執行一次。