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