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是最合適不過的了,插件只需要引用一次,即執行一次。