前六章的內容在上一篇文章中已有介紹,后面的內容主要是一些JQuery的插件的介紹,有一些感覺是很有用的,但是有一些個人覺得構建一個功能需要引入2-3個插件,就有點累贅,所以我覺得學會先學會如何編寫插件才是最適合自己的方法,今天根據書中內容結合自己的理解說說jQuery插件的編寫。
jQuery核心原理
我們通過jQuery()函數可以得到一個jQuery對象,但是實際上,我們得到的jQuery對象并不是jQuery()這個函數創造出來的對象,在這個函數中,原理是
jQuery(){
return new jQuery.fn.init()
}
在jQuery的原型對象有兩個名字,jQuery.prototype == jQuery.fn。jQuery的原型對象有一個constructor屬性,又指回了jQuery,jQuery的原型對象還有一個init屬性,這個init屬性才是真正的構造函數,jQuery原型對象上還有一些first(),last(),eq()等函數,我們知道,每一個函數都有一個prototype指針指向原型對象,每一個原型對象都有一個constructor指針指回構造函數,構造函數創建出來的實例對象,都可以使用原型對象中封裝的屬性和方法。也就是說,通過jQuery.fn.init()創建出來的對象,都可以使用eq(),first(),last()等函數,因為jQuery的原型對象上就有這些方法,那么我們直接把jQuery.fn.init.prototype = jQuery.fn = jQuery.prototype,那么init函數創建出來的對象,就可以使用這些方法了。
總結起來就是說,jQuery的原型對象jQuery.prototypr中有一個init屬性,它才是真正的構造函數,這個構造函數的原型對象又指回了jQuery的原型對象jQuery.prototypr,所以init創建出來的對象,就可以使用jQuery原型對象上的方法。因為init和jQuery的原型對象都是jQuery.prototype,所以init和jQuery創建出來的對象理解上去應該是一樣的。
以下為jQuery源碼截取。
關于鏈式語法
jQuery中比較經典的還有就是鏈式語法,它的實現原理是啥呢?
在每一個jQuery對象方法的末尾,都返回這個對象,那么即可實現鏈式語法。也就是return this、
那么我們模擬一下這個鏈式語法
<script type="text/javascript">
function Person(){
this.name = "小飯";
}
Person.prototype.study = function(){
console.log("飯飯愛學習");
return this;//鏈式語法的核心
}
Person.prototype.eat = function(){
console.log("飯飯愛吃飯");
return this;
}
var Luckfine = new Person();
console.log( Luckfine.study() === Luckfine );
Luckfine.study().eat()
/*
jQuery的核心原理 jQuery.fn.init.prototype == jQuery.prototype
jQuery的鏈式語法 return this;
*/
</script>
運行結果
jQuery === $
在實際使用的時候我們通常是用$來代替jQuery,那么我們是如何實現的呢?
所以就是說jQuery還有個名字叫$.
jQuery插件的基本要點
1、jQuery插件的文件名推薦為jQuery.[插件名].js,一面和其他JavaScript庫插件混淆,例如:jQuery.color.js
2、所有對象方法都應當附加到jQuery.fn對象上,而所有的全局函數都應該附加到jQuery對象本身上
3、在插件內部,this指向的是當前通過選擇器獲取的jQuery對象,而不是像一般方法那樣,例如click()方法,內部this指向的是DOM元素。
4、可以通過this.each來遍歷所有元素
5、所有的方法或函數插件,都應當以分號結尾,否則壓縮的時候可能會出現問題,為了更穩妥一些,甚至可以在插件頭部先加一個分號,以免他人的不規范代碼給插件帶來的影響。
6、插件應該返回一個jQuery對象,以保障插件可以鏈式操作,除非插件需要返回的是一些需要獲取的量,例如字符串或者數組等
7、避免在插件內部使用$作為jQuery對象的別名,而應使用完整的jQuery來表示,這樣可以避免沖突,當然,也可以利用歐冠必報這種技巧來避免這個問題,使插件內部繼續使用$作為jQuery的別名,很多插件都是這么做的
插件的形式
通過jQuery源碼我們能夠看到,jQuery整體就是模仿一個塊級作用域,也就是整體在一個立即執行函數中書寫的,這樣也防止了用戶自己定義的變量和jQuery定義的變量沖突。這種也是利用閉包,顯然閉包不是幾句話就能講清楚的,我們就理解這是一個塊級作用域就好了。
那么我們在封裝自己的jQuery插件的時候,就可以采用這種形式,首先定義一個匿名函數function ( ) { //這里放置代碼 },將其插入到一個立即執行函數中 (function ( ) { //這里放置代碼})(),在第二個括號中,可以將參數傳遞進去,以供函數內部使用。
//為了更好的兼容性,開始前可以有個分號
;( function ( $ ) { //此處將$作為匿名函數的形參
//這里放置代碼,可以使用$作為jQuery的縮寫別名
} )( jQuery ) //這里就將jQuery作為實參傳遞給匿名函數了。
jQuery插件的機制
jQuery提供了兩個用于擴展jQuery功能的方法,即jQuery.fn,extend( ) 和 jQuery.extend ( ) 方法、前者用于擴展對象方法的插件,后者用于封裝全局函數的插件。這兩種方法都接受一個參數,類型為object,object對象的“名/值對”分別代表“函數或方法名/函數主體”,具體內容會在下面講解。
編寫jQuery對象插件
1.編寫設置和獲取顏色的插件
該插件有兩個功能
a,設置匹配元素的顏色
b,獲取匹配的元素(元素集合中的第一個)的顏色
由于是對jQuery對象的方法的擴展,因此采用jQuery.fn.extend( )來編寫,可以給這個方法提供一個參數value,如果調用方法的時候傳遞了value這個參數,那么就是這個值來設置字體顏色,否則就是獲取匹配元素的字體顏色的值。
首先,我們要知道,簡單的調用jQuery提供的css() 方法,直接寫成this.css("color","value")即可。注意,插件內部的this指向的是jQuery對象,而非普通的DOM對象,接下來需要注意的是,插件如果不需要返回字符串之類的特定值,應當使其具有可鏈接性,為此,直接返回這個this對象,由于css()方法會直接返回調用它的對象,那么我 們直接return this.css("color","value")即可。
接下來第二個功能,如果沒有給方法傳遞參數,那么就是獲取集合對象對象中第一個對象的color的值,由于css()本身就有返回第一個匹配元素的樣式值得功能,因此此處無需用eq()來回去第一個元素,只要將這兩個功能 結合起來,判斷一下value是否是undefined即可。
<script src="jquery/jquery-3.0.0.min.js"></script>
<script type="text/javascript">
;(function($){
jQuery.fn.extend({
"color":function(value){
if(value == undefined){
return this.css("color");
}else{
return this.css("color",value);
}
}
})
})(jQuery)
</script>
測試一下該插件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div class="a">red</div>
<div class="blue">blue</div>
<div style="color: green;">green</div>
<div style="color: yellow;">yellow</div>
<script src="jquery/jquery-3.0.0.min.js"></script>
<script type="text/javascript">
;(function($){
jQuery.fn.extend({
"color":function(value){
if(value == undefined){
return this.css("color");
}else{
return this.css("color",value);
}
}
})
})(jQuery)
</script>
<script>
$(function(){
//查看第一個div的color樣式
alert($('div').color())
//返回的object證明得到的jQuery對象
alert($('div').color('red'))
//把所有的div的字體顏色都設為紅色,證明插件好
$('div').color("red")
})
</script>
</body>
</html>
測試效果
2、編寫插件實現點擊標簽改變標簽的背景色
$.fn.extend({
clcikChangeBg:function(){
this.on("click",function(){
$(this).css("background-color","red");
$(this).siblings().css("background-color","#fff");
})
}
})
$("div").clcikChangeBg();
插件效果
3、編寫插件實現單擊雙擊
功能如下:
a,區分單擊雙擊
b,單擊改變顏色,雙擊時候不觸發單擊,只允許隱藏
jQuery.fn.extend({
myClick:function(){
var timer;
this.on("click",function(){
clearTimeout(timer);
var _this=$(this)
timer = setTimeout(function(){
_this.siblings().css("background-color","blue")
_this.css("background-color","orange")
},200)
})
.on("dblclick",function(){
clearTimeout(timer);
$(this).css("background-color","blue")
$(this).fadeOut(800);
})
}
})
$("div").myClick()
效果如下
編寫jQuery全局插件
這類插件是在jQuery命名空間內部添加一個函數,這類插件很簡單,只是普通的函數,利用jQuery.extend( )方法直接對jQuery對象進行擴展。
1.編寫插件實現過濾敏感字
$.extend({
filterWord:function(str){
var keyWords = ["臺獨","藏獨","國民黨"];
for (var i = 0; i < keyWords.length; i++) {
// str = str.replace(keyWords[i],"***");
var r = new RegExp(keyWords[i],"g"); // /臺獨/g
str = str.replace( r,"***")
}
return str;
}
});
console.log( $.filterWord("臺獨規劃局規劃臺獨藏獨藏獨國民黨是什么") );
效果如下
重點
添加到$.extend( ) 上的是全局函數:添加到jQuery.fn.extend( )上的是原型對象上的函數,需要通過jQuery的對象來調用。
編寫插件實現把集合轉換成真正的數組
都知道如果我們jQuery選擇器獲取到的是一個集合,并不是一個數組,如果我們把獲取的集合轉換成數組,那么我們就可以直接使用數組中自帶的方法操作我們的對象,豈不是很方便。
封裝在全局函數中
$.extend({
makeRealArray:function($Arr){
var arr = [];
for (var i = 0; i < $Arr.length; i++) {
arr.push( $Arr[i] );
}
return arr;
}
})
var ret = $.makeRealArray( $("div") )
console.log(ret);//打印這個數組
console.log( Array.isArray(ret) );//判斷對象是否是數組
效果如下
封裝成對象方法
$.fn.extend({
toArray_My:function(){
var arr = [];
this.each(function(index,element){
arr.push(element);
})
return arr;
}
})
console.log( $("div").toArray_My() );
效果如下
兩個方法都是將獲取到的集合轉換成數組,但是封裝的形式不一樣,所以調用的方法是不一樣的,要注意區分。
自己把書看了一遍,結合自己的理解,整理成文章,真是一個耗時的過程。也建議正在看這本書的孩子把里面的例子自己敲一下,會發現里面的有些例子擴展性很強。
喜歡小飯的文章就點贊啦啦拉票啦~