JavaScript插件化開發(fā)教程 (二)
一,開篇分析
Hi,大家好!還記得前面的那篇文章嗎------這個(gè)系列的開篇(JavaScript插件化開發(fā)教程一)。主要講述了以“jQuery的方式如何開發(fā)插件”,
那么今天我們帶著昨天的疑問來(lái)繼續(xù)我們的插件開發(fā)之旅。之前的問題如下:
(1),如果項(xiàng)目技術(shù)選型換了這些插件又是強(qiáng)依賴“jQuery”機(jī)制,我們以前寫的插件將會(huì)不能用(假設(shè)不用jQuery的情況),如何做重構(gòu)那?
(2),重構(gòu)插件的關(guān)鍵邏輯,我們將如何組織那?
好了,帶著問題去學(xué)習(xí)今天的文章吧。
首先我不是否定“jQuery插件的方式”,其次是我們要從不同的角度分析問題,比如說(shuō)“jQuery插件有如下優(yōu)點(diǎn)”:
(1),把全部代碼放在閉包(一個(gè)即時(shí)執(zhí)行函數(shù))里此時(shí)閉包相當(dāng)于一個(gè)私有作用域,外部無(wú)法訪問到內(nèi)部的信息,并且不會(huì)存在全局變量的污染情況。
(2),a) 避免全局依賴;b) 避免第三方破壞;c) 兼容jQuery操作符'$'和'jQuery '。
那我們重構(gòu)將以什么方式組織代碼那,是面向?qū)ο蟮乃枷耄∣OP)那?還是過(guò)程化的思路進(jìn)行到底那?還是兩者結(jié)合設(shè)計(jì)那?哈哈哈,繼續(xù)看。。。。。。
二,重構(gòu)昨天的例子
以下是昨天的Js部分源碼部分:
(function($){
$.fn.bigbear = function(opts){
opts = $.extend({},$.fn.bigbear.defaults,opts) ;
return this.each(function(){
var elem = $(this) ;
elem.find("span").text(opts["title"]) ;
$.get(opts["url"],function(data){
elem.find("div").text(data["text"]) ;
}) ;
}) ;
} ;
$.fn.bigbear.defaults = {
title : "這是一個(gè)簡(jiǎn)單的測(cè)試" ,
url : "data.json"
} ;
})(jQuery) ;
我們來(lái)逐行分析一下:
首先確定一下這個(gè)插件的功能
?。?),顯示我們?cè)O(shè)置的標(biāo)題文字信息。
?。?),動(dòng)態(tài)通過(guò)異步的方式獲取內(nèi)容信息。
好了!需求明確就好展開討論了,從上面的代碼不難看出邏輯組織很松散,過(guò)程化的思維很明顯,所以第一步就是把我們的功能需求
以類的方式有效地組織起來(lái)??慈缦轮貥?gòu)后的代碼:
$(function(){
$("#bb").bigbear() ;
}) ;
(function($){
$.fn.bigbear = function(opts){
opts = $.extend({},$.fn.bigbear.defaults,opts) ;
return this.each(function(){
var elem = $(this) ;
var bb = new BigBear(elem,opts) ;
bb.getElem().trigger("data") ;
}) ;
} ;
$.fn.bigbear.defaults = {
title : "這是一個(gè)簡(jiǎn)單的測(cè)試" ,
url : "data.json"
} ;
})(jQuery) ;
function BigBear(elem,opts){
this.elem = elem ;
this.opts = opts ;
this.init() ;
} ;
var bbProto = BigBear.prototype ;
bbProto.getElem = function(){
return this.elem ;
} ;
bbProto.getOpts = function(){
return this.opts ;
} ;
bbProto.init = function(){
var that = this ;
this.getElem().on("data",function(){
that._setTitle(that.getOpts()["title"]) ;
$.get(that.getOpts()["url"],function(result){
that.getElem().find("div").text(result["text"]) ;
}) ;
}) ;
} ;
bbProto._setTitle = function(text){
this.getElem().find("span").text(text) ;
} ;
哈哈哈,是不是代碼多了不少,其實(shí)這種方式就是面向?qū)ο蟮慕嵌瓤磫栴},先去分析功能需求,然后設(shè)計(jì)我們的類,雖然說(shuō)我們不可能一下設(shè)計(jì)得很出色,
但是看問題角度改變了,我們的代碼可讀性強(qiáng)了,以及更好地進(jìn)行維護(hù)這樣我們的目的也就達(dá)到了。
以下是是摘自“Bootstrap”Js部分的相關(guān)源碼實(shí)現(xiàn),如下圖:

不難看出也是相似的實(shí)現(xiàn)方式,通過(guò)類來(lái)維護(hù)我們插件的主要邏輯。
(三),增加新功能,引出額外的類
現(xiàn)在需求增加了,需要在體驗(yàn)上有所變化,加載數(shù)據(jù)時(shí)有“l(fā)oading”效果。
實(shí)現(xiàn)思路可以這樣,在原始的內(nèi)容區(qū)把文字設(shè)置成“裝載數(shù)據(jù)中。。。?!钡淖謽樱缓笠胍粋€(gè)新的類,如下:
function Overlay(){
} ;
var olProto = Overlay.prototype ;
olProto.show = function(){} ;
olProto.hide = function(){} ;
// 具體實(shí)現(xiàn)就不寫了
好了,遮罩層已經(jīng)有了,現(xiàn)在我們?cè)趺醇蛇M(jìn)來(lái)那?我們用組合的方式接入進(jìn)來(lái),如下:
function BigBear(elem,opts){
this.elem = elem ;
this.opts = opts ;
this.overlay = new Overlay() ;
this.init() ;
} ;
var bbProto = BigBear.prototype ;
bbProto.getElem = function(){
return this.elem ;
} ;
bbProto.getOpts = function(){
return this.opts ;
} ;
bbProto.init = function(){
var that = this ;
var loadingText = "數(shù)據(jù)裝載中。。。" ;
this.getElem().on("data",function(){
that._setTitle(that.getOpts()["title"]) ;
that.overlay.show() ;
that.getElem().find("div").text(loadingText) ;
$.get(that.getOpts()["url"],function(result){
that.overlay.hide() ;
that.getElem().find("div").text(result["text"]) ;
}) ;
}) ;
} ;
bbProto._setTitle = function(text){
this.getElem().find("span").text(text) ;
} ;
到此只為我們的功能就算是結(jié)束了,這樣寫的插件,我相信比第一個(gè)版本好很多,當(dāng)然這不是最優(yōu)的實(shí)現(xiàn),需要從細(xì)節(jié)上不斷重構(gòu),但是這種方式是一種可選的開發(fā)插件的方式。
以下是完整的代碼:
$(function(){
$("#bb").bigbear() ;
}) ;
(function($){
$.fn.bigbear = function(opts){
opts = $.extend({},$.fn.bigbear.defaults,opts) ;
return this.each(function(){
var elem = $(this) ;
var bb = new BigBear(elem,opts) ;
bb.getElem().trigger("data") ;
}) ;
} ;
$.fn.bigbear.defaults = {
title : "這是一個(gè)簡(jiǎn)單的測(cè)試" ,
url : "data.json"
} ;
})(jQuery) ;
function BigBear(elem,opts){
this.elem = elem ;
this.opts = opts ;
this.overlay = new Overlay() ;
this.init() ;
} ;
var bbProto = BigBear.prototype ;
bbProto.getElem = function(){
return this.elem ;
} ;
bbProto.getOpts = function(){
return this.opts ;
} ;
bbProto.init = function(){
var that = this ;
var loadingText = "數(shù)據(jù)裝載中。。。" ;
this.getElem().on("data",function(){
that._setTitle(that.getOpts()["title"]) ;
that.overlay.show() ;
that.getElem().find("div").text(loadingText) ;
$.get(that.getOpts()["url"],function(result){
that.overlay.hide() ;
that.getElem().find("div").text(result["text"]) ;
}) ;
}) ;
} ;
bbProto._setTitle = function(text){
this.getElem().find("span").text(text) ;
} ;
function Overlay(){
} ;
var olProto = Overlay.prototype ;
olProto.show = function(){} ;
olProto.hide = function(){} ;
// 具體實(shí)現(xiàn)就不寫了
本文暫時(shí)先到這里了,小伙伴們是否對(duì)插件化開發(fā)javascript有了新的認(rèn)識(shí)了呢。
- JavaScript插件化開發(fā)教程(六)
- JavaScript插件化開發(fā)教程(五)
- JavaScript插件化開發(fā)教程 (四)
- JavaScript插件化開發(fā)教程 (三)
- JavaScript插件化開發(fā)教程 (一)
- 一看就懂的Android APP開發(fā)入門教程
- Android中利用App實(shí)現(xiàn)消息推送機(jī)制的代碼
- Android筆記之:App應(yīng)用之啟動(dòng)界面SplashActivity的使用
- Android 避免APP啟動(dòng)閃黑屏的解決辦法(Theme和Style)
- 親自動(dòng)手實(shí)現(xiàn)Android App插件化
相關(guān)文章
一文讓你徹底弄懂js中undefined和null的區(qū)別
JavaScript是一門動(dòng)態(tài)類型語(yǔ)言,元素除了表示存在的空值外,還有可能根本就不存在,這就是undefined存在的原因,這篇文章主要給大家介紹了關(guān)于undefined和null區(qū)別的相關(guān)資料,需要的朋友可以參考下2022-03-03
JavaScript調(diào)用傳遞變量參數(shù)的相關(guān)問題及解決辦法
本文給大家介紹javascript調(diào)用傳遞變量參數(shù)的相關(guān)問題及解決辦法,涉及到j(luò)s調(diào)用傳遞參數(shù)相關(guān)知識(shí),對(duì)js調(diào)用傳遞參數(shù)感興趣的朋友一起學(xué)習(xí)吧2015-11-11
js 在定義的時(shí)候立即執(zhí)行的函數(shù)表達(dá)式(function)寫法
如果不需要顯示調(diào)用函數(shù), 讓這個(gè)函數(shù)在定義的時(shí)候就執(zhí)行的話, 該如何寫才可以呢,接下來(lái)將詳細(xì)介紹實(shí)現(xiàn)步驟,感興趣的朋友可以了解下2013-01-01
添加、刪除HTML結(jié)點(diǎn) & 上傳圖片預(yù)覽
添加、刪除HTML結(jié)點(diǎn) & 上傳圖片預(yù)覽...2006-10-10
給事件響應(yīng)函數(shù)傳參數(shù)的四種方式小結(jié)
這篇文章主要介紹了給事件響應(yīng)函數(shù)傳參數(shù)的四種方式。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-12-12
JS實(shí)現(xiàn)仿FLASH效果的豎排導(dǎo)航代碼
這篇文章主要介紹了JS實(shí)現(xiàn)仿FLASH效果的豎排導(dǎo)航代碼,涉及JavaScript基于定時(shí)函數(shù)動(dòng)態(tài)設(shè)置頁(yè)面元素樣式的技巧,具有FLASH變換效果,需要的朋友可以參考下2015-09-09
webpack學(xué)習(xí)--webpack經(jīng)典7分鐘入門教程
這篇文章主要介紹了webpack學(xué)習(xí)--webpack經(jīng)典7分鐘入門教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
javascript中alert()與console.log()的區(qū)別
我們?cè)谧鰆s調(diào)試的時(shí)候使用 alert 可以顯示信息,調(diào)試程序,alert 彈出窗口會(huì)中斷程序, 如果要在循環(huán)中顯示信息,手點(diǎn)擊關(guān)閉窗口都累死。而且 alert 顯示對(duì)象永遠(yuǎn)顯示為[object ]。 自己寫的 log 雖然可以顯示一些 object 信息,但很多功能支持都沒有 console 好2015-08-08
JavaScript原型鏈與繼承操作實(shí)例總結(jié)
這篇文章主要介紹了JavaScript原型鏈與繼承操作,結(jié)合實(shí)例形式總結(jié)分析了javascript原形鏈與繼承的相關(guān)概念、使用方法及操作注意事項(xiàng),需要的朋友可以參考下2018-08-08

