在jQuery大量使用的環(huán)境下,,目前網(wǎng)上的眾多jQuery插件也能基本滿足要求,但是在項目具體需求下,有時候依舊需要自己造輪子,,本文介紹了如何不依賴jQuery等庫進(jìn)行原生JavsScript插件的編寫。
插件需要滿足的條件
一個可復(fù)用的插件需要滿足以下條件:
- 插件自身的作用域與用戶當(dāng)前的作用域相互獨(dú)立,也就是插件內(nèi)部的私有變量不能影響使用者的環(huán)境變量;
- 插件需具備默認(rèn)設(shè)置參數(shù),;
- 插件除了具備已實現(xiàn)的基本功能外,需提供部分API,,使用者可以通過該API修改插件功能的默認(rèn)參數(shù),,從而實現(xiàn)用戶自定義插件效果;
- 插件需提供監(jiān)聽入口,,及針對指定元素進(jìn)行監(jiān)聽,,使得該元素與插件響應(yīng)達(dá)到插件效果;
- 插件支持鏈?zhǔn)秸{(diào)用,。
以下便針對這四點要求進(jìn)行逐個講解,,以實現(xiàn)自定義的原生插件。
1,、插件全局函數(shù)
實現(xiàn)私有作用域,,最好的辦法就是使用閉包??梢园巡寮?dāng)做一個函數(shù),,插件內(nèi)部的變量及函數(shù)的私有變量,,為了在調(diào)用插件后依舊能使用其功能,,閉包的作用就是延長函數(shù)(插件)內(nèi)部變量的生命周期,使得插件函數(shù)可以重復(fù)調(diào)用,,而不影響用戶自身作用域,。
故需將插件的所有功能寫在一個立即執(zhí)行函數(shù)中:
(function () {
//插件所有功能都寫在這個函數(shù)下
})();
2、插件默認(rèn)參數(shù)
插件的主要功能可以總結(jié)至幾個關(guān)鍵參數(shù),,通過這幾個關(guān)鍵參數(shù)即可修改插件的主要功能,,也是第三步API設(shè)置的關(guān)鍵參數(shù),。
將默認(rèn)參數(shù)放置在全局函數(shù)的最前面,參數(shù)變量名為options,通過對象字面量進(jìn)行賦值:
var options = {
key1: para1,
key2: para2,
key3: para3,
...
keyn: paran
}
key即為可以插件變量名字,,para為該變量對應(yīng)的值,。如我需要編寫一個設(shè)置顏色的插件,默認(rèn)顏色為黑色,,option應(yīng)為:
var options = {
color: '#333333'
}
編寫功能部分時調(diào)用方式:options.color ,。
3、插件API,、參數(shù)設(shè)置和監(jiān)聽
因為API指向的是使用者,,故需要在用戶調(diào)用插件時將API暴露給用戶,因用戶API時是通過插件提供的名字進(jìn)行使用,,故將API設(shè)置為Object類型,,用戶就可以通過調(diào)用API的key進(jìn)行使用,具體的代碼如下:
var api = {
config: function (ops) {
//....
return this;
},
listen: function listen(elem) {
//...
return this;
},
feature1: function() {
//...
},
feature2: function() {
//...
}
}
this.pluginName = api;
上面提供了api的寫法示范,,該api提供了config以設(shè)置自定義參數(shù),,listen為插件監(jiān)聽的dom操作,feature為插件的主要功能,,使用options參數(shù)的功能都要寫在api下,,注意api.config 和api.listen 兩個函數(shù)都應(yīng)該在最后返回this ,以便實現(xiàn)插件的鏈?zhǔn)秸{(diào)用,。
有了上面的框架,,針對config 設(shè)置函數(shù)的寫法就有了明確的要求:在用戶沒有傳入自定義函數(shù)時,默認(rèn)使用上一節(jié)options中的參數(shù),,如果用戶有設(shè)置config參數(shù),,使用用戶自定義參數(shù):
config: function (opts) {
//沒有參數(shù)傳入,直接返回默認(rèn)參數(shù)
if(!opts) return options;
//有參數(shù)傳入,,通過key將options的值更新為用戶的值
for(var key in opts) {
options[key] = opts[key];
}
return this;
}
針對元素的監(jiān)聽listen,,需要對所有符合條件的dom元素進(jìn)行監(jiān)聽:
listen: function listen(elem) {
//這里通過typeof設(shè)置監(jiān)聽的元素需為字符串調(diào)用,實際可根據(jù)需要進(jìn)行更改
if (typeof elem === 'string') {
//這里使用ES5的querySelectorAll方法獲取dom元素
var elems = document.querySelectorAll(elem),
i = elems.length;
//通過遞歸將listen方法應(yīng)用在所有的dom元素上
while (i--) {
listen(elems[i]);
}
return
}
//在這里,,你可以將插件的部分功能函數(shù)寫在這里
return this;
}
在config和listen這兩個最基本的API完成后,,需要將API與插件的名字結(jié)合起來:
則最基本的API如下:
var api = {
//插件參數(shù)設(shè)定
config: function (opts) {
if(!opts) return options;
for(var key in opts) {
options[key] = opts[key];
}
return this;
},
//插件監(jiān)聽
listen: function listen(elem) {
if (typeof elem === 'string') {
var elems = document.querySelectorAll(elem),
i = elems.length;
while (i--) {
listen(elems[i]);
}
return
}
//插件功能函數(shù)可以寫在這
return this;
}
}
//將API賦值給插件名字
this.pluginName = api;
則用戶使用該插件時,調(diào)用方式為:
pluginName.listen('#demo');
如需要自定義參數(shù):
pluginName.config({key: 'para'}).listen('#demo');
//因為config和listen已經(jīng)返回this,,所有可以這樣調(diào)用:
pluginName.listen('#demo').config({key: 'para'});
//還可以這樣調(diào)用:
pluginName.config({key: 'para'})
.listen('#demo');
4,、結(jié)語
以上介紹了原生插件的基本框架的寫法,在我的github上還提供了幾個由jQuery插件轉(zhuǎn)化過來的原生插件實例:
ColorDivideJS
domzoom.js
在這個基礎(chǔ)框架基礎(chǔ)上,,可以擴(kuò)展出符合項目具體要求的特定插件,。同時這樣的插件沒有其他庫依賴,也具有更強(qiáng)的復(fù)用性。
(完)
|