JavaScript插件化开发
大熊君JavaScript插件化开发
一,开篇分析
Hi,大家好!大熊君又和大家见面了,还记得昨天的那篇文章吗------这个系列的开篇(第一季)。主要讲述了以“jQuery的方式如何开发插件”,
那么今天我们带着昨天的疑问来继续我们的插件开发之旅。昨天的问题如下:
(1),如果项目技术选型换了这些插件又是强依赖“jQuery”机制,我们以前写的插件将会不能用(假设不用jQuery的情况),如何做重构那?
(2),重构插件的关键逻辑,我们将如何组织那?
好了,带着问题去学习今天的文章吧。
首先我不是否定“jQuery插件的方式”,其次是我们要从不同的角度分析问题,比如说“jQuery插件有如下优点”:
(1),把全部代码放在闭包(一个即时执行函数)里此时闭包相当于一个私有作用域,外部无法访问到内部的信息,并且不会存在全局变量的污染情况。
(2),a) 避免全局依赖;b) 避免第三方破坏;c) 兼容jQuery操作符'$'和'jQuery '。
那我们重构将以什么方式组织代码那,是面向对象的思想(OOP)那?还是过程化的思路进行到底那?还是两者结合设计那?哈哈哈,继续看。。。。。。
二,重构昨天的例子
以下是昨天的Js部分源码部分:

1 (function($){
2 $.fn.bigbear = function(opts){
3 opts = $.extend({},$.fn.bigbear.defaults,opts) ;
4 return this.each(function(){
5 var elem = $(this) ;
6 elem.find("span").text(opts["title"]) ;
7 $.get(opts["url"],function(data){
8 elem.find("div").text(data["text"]) ;
9 }) ;
10 }) ;
11 } ;
12 $.fn.bigbear.defaults = {
13 title : "这是一个简单的测试" ,
14 url : "data.json"
15 } ;
16 })(jQuery) ;

我们来逐行分析一下:
首先确定一下这个插件的功能
(1),显示我们设置的标题文字信息。
(2),动态通过异步的方式获取内容信息。
好了!需求明确就好展开讨论了,从上面的代码不难看出逻辑组织很松散,过程化的思维很明显,所以第一步就是把我们的功能需求
以类的方式有效地组织起来。看如下重构后的代码:

1 $(function(){
2 $("#bb").bigbear() ;
3 }) ;
4 (function($){
5 $.fn.bigbear = function(opts){
6 opts = $.extend({},$.fn.bigbear.defaults,opts) ;
7 return this.each(function(){
8 var elem = $(this) ;
9 var bb = new BigBear(elem,opts) ;
10 bb.getElem().trigger("data") ;
11 }) ;
12 } ;
13 $.fn.bigbear.defaults = {
14 title : "这是一个简单的测试" ,
15 url : "data.json"
16 } ;
17 })(jQuery) ;
18
19 function BigBear(elem,opts){
20 this.elem = elem ;
21 this.opts = opts ;
22 this.init() ;
23 } ;
24 var bbProto = BigBear.prototype ;
25 bbProto.getElem = function(){
26 return this.elem ;
27 } ;
28 bbProto.getOpts = function(){
29 return this.opts ;
30 } ;
31 bbProto.init = function(){
32 var that = this ;
33 this.getElem().on("data",function(){
34 that._setTitle(that.getOpts()["title"]) ;
35 $.get(that.getOpts()["url"],function(result){
36 that.getElem().find("div").text(result["text"]) ;
37 }) ;
38 }) ;
39 } ;
40 bbProto._setTitle = function(text){
41 this.getElem().find("span").text(text) ;
42 } ;

哈哈哈,是不是代码多了不少,其实这种方式就是面向对象的角度看问题,先去分析功能需求,然后设计我们的类,虽然说我们不可能一下设计得很出色,
但是看问题角度改变了,我们的代码可读性强了,以及更好地进行维护这样我们的目的也就达到了。
以下是是摘自“Bootstrap”Js部分的相关源码实现,如下图:

不难看出也是相似的实现方式,通过类来维护我们插件的主要逻辑。
(三),增加新功能,引出额外的类
现在需求增加了,需要在体验上有所变化,加载数据时有“loading”效果。
实现思路可以这样,在原始的内容区把文字设置成“装载数据中。。。。”的字样,然后引入一个新的类,如下:

1 function Overlay(){
2
3 } ;
4 var olProto = Overlay.prototype ;
5 olProto.show = function(){} ;
6 olProto.hide = function(){} ;
7 // 具体实现就不写了

好了,遮罩层已经有了,现在我们怎么集成进来那?我们用组合的方式接入进来,如下:

1 function BigBear(elem,opts){
2 this.elem = elem ;
3 this.opts = opts ;
4 this.overlay = new Overlay() ;
5 this.init() ;
6 } ;
7 var bbProto = BigBear.prototype ;
8 bbProto.getElem = function(){
9 return this.elem ;
10 } ;
11 bbProto.getOpts = function(){
12 return this.opts ;
13 } ;
14 bbProto.init = function(){
15 var that = this ;
16 var loadingText = "数据装载中。。。" ;
17 this.getElem().on("data",function(){
18 that._setTitle(that.getOpts()["title"]) ;
19 that.overlay.show() ;
20 that.getElem().find("div").text(loadingText) ;
21 $.get(that.getOpts()["url"],function(result){
22 that.overlay.hide() ;
23 that.getElem().find("div").text(result["text"]) ;
24 }) ;
25 }) ;
26 } ;
27 bbProto._setTitle = function(text){
28 this.getElem().find("span").text(text) ;
29 } ;

到此只为我们的功能就算是结束了,这样写的插件,我相信比第一个版本好很多,当然这不是最优的实现,需要从细节上不断重构,但是这种方式是一种可选的开发插件的方式。
以下是完整的代码:

1 $(function(){
2 $("#bb").bigbear() ;
3 }) ;
4 (function($){
5 $.fn.bigbear = function(opts){
6 opts = $.extend({},$.fn.bigbear.defaults,opts) ;
7 return this.each(function(){
8 var elem = $(this) ;
9 var bb = new BigBear(elem,opts) ;
10 bb.getElem().trigger("data") ;
11 }) ;
12 } ;
13 $.fn.bigbear.defaults = {
14 title : "这是一个简单的测试" ,
15 url : "data.json"
16 } ;
17 })(jQuery) ;
18
19 function BigBear(elem,opts){
20 this.elem = elem ;
21 this.opts = opts ;
22 this.overlay = new Overlay() ;
23 this.init() ;
24 } ;
25 var bbProto = BigBear.prototype ;
26 bbProto.getElem = function(){
27 return this.elem ;
28 } ;
29 bbProto.getOpts = function(){
30 return this.opts ;
31 } ;
32 bbProto.init = function(){
33 var that = this ;
34 var loadingText = "数据装载中。。。" ;
35 this.getElem().on("data",function(){
36 that._setTitle(that.getOpts()["title"]) ;
37 that.overlay.show() ;
38 that.getElem().find("div").text(loadingText) ;
39 $.get(that.getOpts()["url"],function(result){
40 that.overlay.hide() ;
41 that.getElem().find("div").text(result["text"]) ;
42 }) ;
43 }) ;
44 } ;
45 bbProto._setTitle = function(text){
46 this.getElem().find("span").text(text) ;
47 } ;
48
49 function Overlay(){
50
51 } ;
52 var olProto = Overlay.prototype ;
53 olProto.show = function(){} ;
54 olProto.hide = function(){} ;
55 // 具体实现就不写了

(四),最后总结
(1),面向对象的思考方式合理分析功能需求。
(2),以类的方式来组织我们的插件逻辑。
(3),不断重构上面的实例,最好自己写一下,并且完善“Overlay”的逻辑。
(4),大家学习完继续思考一下,如何进行合理的重构那?不要设计过度,要游刃有余,推荐的方式是过程化设计与面向对象思想设计相结合。
哈哈哈,本篇结束,未完待续,希望和大家多多交流够沟通,共同进步。。。。。。呼呼呼……(*^__^*)
JavaScript插件化开发的更多相关文章
- 大熊君JavaScript插件化开发------(第一季)
一,开篇分析 Hi,大家!大熊君又来了,今天这系列文章主要是说说如何开发基于“JavaScript”的插件式开发,我想很多人对”插件“这个词并不陌生, 有的人可能叫“组件”或“部件”,这不重要,关键是 ...
- 大熊君JavaScript插件化开发------(实战篇之DXJ UI ------ ItemSelector重构完结版)
一,开篇分析 Hi,大家好!大熊君又和大家见面了,还记得上一篇文章吗.主要讲述了以“jQuery的方式如何开发插件”,以及过程化设计与面向对象思想设计相结合的方式是 如何设计一个插件的,两种方式各有利 ...
- 大熊君JavaScript插件化开发------(实战篇之DXJ UI ------ ItemSelector)
一,开篇分析 Hi,大家好!大熊君又和大家见面了,还记得前两篇文章吗.主要讲述了以“jQuery的方式如何开发插件”,以及过程化设计与面向对象思想设计相结合的方式是 如何设计一个插件的,两种方式各有利 ...
- 大熊君JavaScript插件化开发------(实战篇之DXJ UI ------ ProcessBar)
一,开篇分析 Hi,大家好!大熊君又和大家见面了,还记得前两篇文章吗.主要讲述了以“jQuery的方式如何开发插件”,以及过程化设计与面向对象思想设计相结合的方式是 如何设计一个插件的,两种方式各有利 ...
- 大熊君JavaScript插件化开发------(实战篇之DXJ UI ------ Tab)
一,开篇分析 Hi,大家好!大熊君又和大家见面了,还记得前两篇文章吗.主要讲述了以“jQuery的方式如何开发插件”,以及过程化设计与面向对象思想设计相结合的方式是 如何设计一个插件的,两种方式各有利 ...
- 大熊君JavaScript插件化开发------(第二季)
一,开篇分析 Hi,大家好!大熊君又和大家见面了,还记得昨天的那篇文章吗------这个系列的开篇(第一季).主要讲述了以“jQuery的方式如何开发插件”, 那么今天我们带着昨天的疑问来继续我们的插 ...
- 大熊君JavaScript插件化开发------(实战篇之DXJ UI ------ Tab功能扩展完结版)
一,开篇分析 Hi,大家好!大熊君又和大家见面了,还记得上一篇文章吗.主要讲述了一个“Tab”插件是如何组织代码以及实现的”,以及过程化设计与面向对象思想设计相结合的方式是 如何设计一个插件的,两种方 ...
- TinyFrame升级之八:实现简易插件化开发
本章主要讲解如何为框架新增插件化开发功能. 在.net 4.0中,我们可以在Application开始之前,通过PreApplicationStartMethod方法加载所需要的任何东西.那么今天我们 ...
- Android组件化和插件化开发
http://www.cnblogs.com/android-blogs/p/5703355.html 什么是组件化和插件化? 组件化开发就是将一个app分成多个模块,每个模块都是一个组件(Modul ...
随机推荐
- redis基础的字符串类型
redis —— 第二篇 基础的字符串类型 我们都知道redis是采用C语言开发,那么在C语言中表示string都是采用char[]数组的,然后你可能会想,那还不简单,当我执行如下命令,肯定是直 接塞 ...
- php脚本生成google play url的下载链接,下载apk并自动反编译后获取android版本号
需求: get the offer tracking link follow the redirect to get google play url Go to http: ...
- 微软MVP社区夏日巡讲诚邀您的参与: 北京,上海,西宁,成都,西安
- SQL入门学习4-复杂查询
5-1 视图 视图和表 视图和表的区别只有一个是否保存了实际的数据 使用INSERT和SELECT实际上就是从存储设备中读取数据,各种计算后,将数据呈现给用户. 视图不会将数据保存在存储设备中.实际上 ...
- SQLite外键
数据库工具:SQLite Manager(V0.7.7) SQLite版本号:V3.6.19+ SQLite Manager 默认是不开启外键的. 那么怎样,使用它创建一个带有外键的表呢? 一.开启外 ...
- cocos2d 消除类游戏简单的算法 (一)
1. 游戏视频演示 2.三消游戏我的理解 上面视频中的游戏.我做了2个星期时间,仅仅能算个简单Demo,还有bug.特效也差点儿没有.感觉三消游戏主要靠磨.越磨越精品. 市场上三消游戏已经超级多了.主 ...
- jQuery整理笔记5----jQuery大事
一.大事 1.载入中DOM $(document).ready() 这个第一节里具体介绍了 2.事件绑定 jQuery定义了bind()方法作为统一的接口.用来为每个匹配元素绑定事件处理程序.其基本的 ...
- dotNET跨平台相关文档
dotNET跨平台相关文档整理 一直在从事C#开发的相关技术工作,从C# 1.0一路用到现在的C# 6.0, 通常情况下被局限于Windows平台,Mono项目把我们C#程序带到了Windows之外的 ...
- 十天学Linux内核之第八天---构建Linux内核
原文:十天学Linux内核之第八天---构建Linux内核 今天是腊八节,说好的女票要给我做的腊八粥就这样泡汤了,好伤心,好心酸呀,看来代码写久了真的是惹人烦滴,所以告诫各位技术男敲醒警钟,不要想我看 ...
- linux
核心学习书籍
1<LINUX程序设计> 基础是非常重要的 2<UNIX环境高级编程> 还是基础 ,假设你是搞UNIX/Linux环境下的应用程序编程,那么就看 3, <Linux内核设 ...