JavaScript插件化開發(fā)教程 (二)
一,開篇分析
Hi,大家好!還記得前面的那篇文章嗎------這個系列的開篇(JavaScript插件化開發(fā)教程一)。主要講述了以“jQuery的方式如何開發(fā)插件”,
那么今天我們帶著昨天的疑問來繼續(xù)我們的插件開發(fā)之旅。之前的問題如下:
(1),如果項目技術選型換了這些插件又是強依賴“jQuery”機制,我們以前寫的插件將會不能用(假設不用jQuery的情況),如何做重構那?
(2),重構插件的關鍵邏輯,我們將如何組織那?
好了,帶著問題去學習今天的文章吧。
首先我不是否定“jQuery插件的方式”,其次是我們要從不同的角度分析問題,比如說“jQuery插件有如下優(yōu)點”:
(1),把全部代碼放在閉包(一個即時執(zhí)行函數(shù))里此時閉包相當于一個私有作用域,外部無法訪問到內(nèi)部的信息,并且不會存在全局變量的污染情況。
(2),a) 避免全局依賴;b) 避免第三方破壞;c) 兼容jQuery操作符'$'和'jQuery '。
那我們重構將以什么方式組織代碼那,是面向對象的思想(OOP)那?還是過程化的思路進行到底那?還是兩者結合設計那?哈哈哈,繼續(xù)看。。。。。。
二,重構昨天的例子
以下是昨天的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 : "這是一個簡單的測試" ,
url : "data.json"
} ;
})(jQuery) ;
我們來逐行分析一下:
首先確定一下這個插件的功能
?。?),顯示我們設置的標題文字信息。
?。?),動態(tài)通過異步的方式獲取內(nèi)容信息。
好了!需求明確就好展開討論了,從上面的代碼不難看出邏輯組織很松散,過程化的思維很明顯,所以第一步就是把我們的功能需求
以類的方式有效地組織起來??慈缦轮貥嫼蟮拇a:
$(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 : "這是一個簡單的測試" ,
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) ;
} ;
哈哈哈,是不是代碼多了不少,其實這種方式就是面向對象的角度看問題,先去分析功能需求,然后設計我們的類,雖然說我們不可能一下設計得很出色,
但是看問題角度改變了,我們的代碼可讀性強了,以及更好地進行維護這樣我們的目的也就達到了。
以下是是摘自“Bootstrap”Js部分的相關源碼實現(xiàn),如下圖:
不難看出也是相似的實現(xiàn)方式,通過類來維護我們插件的主要邏輯。
(三),增加新功能,引出額外的類
現(xiàn)在需求增加了,需要在體驗上有所變化,加載數(shù)據(jù)時有“l(fā)oading”效果。
實現(xiàn)思路可以這樣,在原始的內(nèi)容區(qū)把文字設置成“裝載數(shù)據(jù)中。。。?!钡淖謽樱缓笠胍粋€新的類,如下:
function Overlay(){
} ;
var olProto = Overlay.prototype ;
olProto.show = function(){} ;
olProto.hide = function(){} ;
// 具體實現(xiàn)就不寫了
好了,遮罩層已經(jīng)有了,現(xiàn)在我們怎么集成進來那?我們用組合的方式接入進來,如下:
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) ;
} ;
到此只為我們的功能就算是結束了,這樣寫的插件,我相信比第一個版本好很多,當然這不是最優(yōu)的實現(xiàn),需要從細節(jié)上不斷重構,但是這種方式是一種可選的開發(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 : "這是一個簡單的測試" ,
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(){} ;
// 具體實現(xiàn)就不寫了
本文暫時先到這里了,小伙伴們是否對插件化開發(fā)javascript有了新的認識了呢。
相關文章
解決使用layui的時候form表單中的select等不能渲染的問題
今天小編就為大家分享一篇解決使用layui的時候form表單中的select等不能渲染的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09JavaScript統(tǒng)計網(wǎng)站訪問次數(shù)的實現(xiàn)代碼
每一個稱職的網(wǎng)管,都需要知道每天網(wǎng)站的訪問量,需要實現(xiàn)網(wǎng)站訪問次數(shù)功能來滿足需求,本篇文章主要介紹了JavaScript統(tǒng)計網(wǎng)站訪問次數(shù)的實現(xiàn)代碼,感興趣的小伙伴們可以參考一下2015-11-11JS實現(xiàn)點擊下拉菜單把選擇的內(nèi)容同步到input輸入框內(nèi)的實例
下面小編就為大家分享一篇JS實現(xiàn)點擊下拉菜單把選擇的內(nèi)容同步到input輸入框內(nèi)的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01JavaScript中雙等號(==)和三等號(===)有何不同以及何時使用它們詳解
這篇文章主要給大家介紹了關于JavaScript中雙等號(==)和三等號(===)有何不同以及何時使用它們的相關資料,在JavaScript中"=="和"==="都是比較運算符,用于比較兩個值是否相等,需要的朋友可以參考下2024-01-01javascript 獲取多條數(shù)據(jù)(模擬ajax獲取數(shù)據(jù))
javascript 獲取多條數(shù)據(jù)(模擬ajax獲取數(shù)據(jù)),這樣的好處不用額外的ajax讀取鏈接,減輕服務器負擔。2009-06-06