$("a").css("color", "red");
當使用$
選擇元素的時候,它會返回一個jQuery對象,這個對象中包含了你一直使用的方法(好比:.css(),.click()等)。這個jQuery對象是從$.fn
對象中獲得的這些方法。$.fn
對象包含了jQuery對象的全部方法,若是想編寫咱們本身的方法,也要將方法定義在$.fn
對象裏面。使用這種方式編寫插件,即jQuery類的實例將會擁有此功能。爲何會有這種效果?簡單看下源碼javascript
jQuery.fn = jQuery.prototype ={ init: function( selector, context ){ //do something... };
從源碼可知,當使用$.fn
的方式編寫插件時,就是在jQuery的原型中綁定新的方法,因此根據原型的特性,新建立的jQuery對象天然會擁有新綁定的方法。css
目的:改變a
標籤的字體顏色
作法:建立名爲greenify
的方法,將其加在$.fn
裏面。
如此一來,greenify
方法適用於全部的jQuery對象了html
<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({})
java
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"); });
鏈式編程的好處就是當調用完一個方法後,能夠在後面繼續調用該對象的其餘方法。jquery
$
在JavaScript庫中使用是很是普遍的,若是你正在使用的其餘JavaScript類庫中也使用到了$
,而且你也使用了jQuery,那麼你不得不使用jQuery.noConflict()
來解除衝突。顯然這會破壞咱們的插件,由於它是在假設$
是jQuery函數的別名(實際上$
原本就是jQuery的別名)若是既想使用其餘插件,也要使用jQuery的$
別名,咱們須要將代碼放進當即執行函數(文章結尾會對其簡單解釋)中,而後將jQuery做爲實參傳遞進去,$
做爲形參接收。chrome
(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);
做用:防止多個文件壓縮合並後,前一個文件最後一行語句沒加分號,而引發合併後的語法錯誤。
若是前面已經加了分號,此時就會多出來一個分號,但這樣是不會報錯的。即不怕多,就怕少。性能
;(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
則直接返回第一個參數。
當即執行函數((Immediately-Invoked Function Expression)也稱爲自調用函數,函數定義好後會自動執行。(function(){})
表示一個匿名函數,後面緊跟一個()
,表示當即執行函數。
(function(){ console.log("我會當即執行"); })() (function(param){ console.log(param); //我會馬上執行 })("我會馬上執行");
優勢:不會產生產生全局變量,不會形成變量污染。
缺點:只能執行一次,無法重複執行。
在編寫插件時,使用IIFE是最合適不過的了,插件只須要引用一次,即執行一次。