JavaScript插件化开发教程 (二)


Posted in Javascript onJanuary 27, 2015

一,开篇分析

Hi,大家好!还记得前面的那篇文章吗------这个系列的开篇(JavaScript插件化开发教程一)。主要讲述了以“jQuery的方式如何开发插件”,

那么今天我们带着昨天的疑问来继续我们的插件开发之旅。之前的问题如下:

(1),如果项目技术选型换了这些插件又是强依赖“jQuery”机制,我们以前写的插件将会不能用(假设不用jQuery的情况),如何做重构那?

(2),重构插件的关键逻辑,我们将如何组织那?

好了,带着问题去学习今天的文章吧。

首先我不是否定“jQuery插件的方式”,其次是我们要从不同的角度分析问题,比如说“jQuery插件有如下优点”:

(1),把全部代码放在闭包(一个即时执行函数)里此时闭包相当于一个私有作用域,外部无法访问到内部的信息,并且不会存在全局变量的污染情况。

(2),a) 避免全局依赖;b) 避免第三方破坏;c) 兼容jQuery操作符'$'和'jQuery '。

那我们重构将以什么方式组织代码那,是面向对象的思想(OOP)那?还是过程化的思路进行到底那?还是两者结合设计那?哈哈哈,继续看。。。。。。

二,重构昨天的例子

以下是昨天的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) ;

 我们来逐行分析一下:

首先确定一下这个插件的功能

(1),显示我们设置的标题文字信息。

(2),动态通过异步的方式获取内容信息。

好了!需求明确就好展开讨论了,从上面的代码不难看出逻辑组织很松散,过程化的思维很明显,所以第一步就是把我们的功能需求

以类的方式有效地组织起来。看如下重构后的代码:

$(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部分的相关源码实现,如下图:

JavaScript插件化开发教程 (二)

不难看出也是相似的实现方式,通过类来维护我们插件的主要逻辑。

(三),增加新功能,引出额外的类

现在需求增加了,需要在体验上有所变化,加载数据时有“loading”效果。

实现思路可以这样,在原始的内容区把文字设置成“装载数据中。。。。”的字样,然后引入一个新的类,如下:

function Overlay(){
} ;

var olProto = Overlay.prototype ;

olProto.show = function(){} ;

olProto.hide = function(){} ;

// 具体实现就不写了

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

 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 = "数据装载中。。。" ;

     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(){

    $("#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 = "数据装载中。。。" ;

    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(){} ;

// 具体实现就不写了

本文暂时先到这里了,小伙伴们是否对插件化开发javascript有了新的认识了呢。

Javascript 相关文章推荐
JS 动态获取节点代码innerHTML分析 [IE,FF]
Nov 30 Javascript
JSONP跨域的原理解析及其实现介绍
Mar 22 Javascript
字段太多jquey快速清空表单内容方法
Aug 21 Javascript
jQuery入门介绍之基础知识
Jan 13 Javascript
javascript中的Function.prototye.bind
Jun 25 Javascript
drag-and-drop实现图片浏览器预览
Aug 06 Javascript
js格式化时间的方法
Dec 18 Javascript
jQuery插件制作的实例教程
May 16 Javascript
Javascript将双字节字符转换成单字节字符并计算长度
Jun 22 Javascript
Servlet实现文件上传,可多文件上传示例
Dec 05 Javascript
浅谈react性能优化的方法
Sep 05 Javascript
JS实现transform实现扇子效果
Jan 17 Javascript
javascript将数字转换整数金额大写的方法
Jan 27 #Javascript
JS实现同时搜索百度和必应的方法
Jan 27 #Javascript
js获取域名的方法
Jan 27 #Javascript
JavaScript插件化开发教程 (一)
Jan 27 #Javascript
js的toLowerCase方法用法实例
Jan 27 #Javascript
js的toUpperCase方法用法实例
Jan 27 #Javascript
JS输入用户名自动显示邮箱后缀列表的方法
Jan 27 #Javascript
You might like
PHP调用Linux的命令行执行文件压缩命令
2013/01/27 PHP
解析PHP中的unset究竟会不会释放内存
2013/07/18 PHP
php判断正常访问和外部访问的示例
2014/02/10 PHP
教你如何开启shopnc b2b2c 伪静态
2014/10/21 PHP
jQuery textarea的长度进行验证
2009/05/06 Javascript
js 数组实现一个类似ruby的迭代器
2009/10/27 Javascript
js 实现打印网页中定义的部分内容的代码
2010/04/01 Javascript
jQuery实现 注册时选择阅读条款 左右移动
2013/04/11 Javascript
jquery foreach使用示例
2013/09/12 Javascript
实现动画效果核心方式的js代码
2013/09/27 Javascript
jQuery异步验证用户名是否存在示例代码
2014/05/21 Javascript
45个JavaScript编程注意事项、技巧大全
2015/02/11 Javascript
jQuery实现在列表的首行添加数据
2015/05/19 Javascript
jQuery实现底部浮动窗口效果
2016/09/07 Javascript
Node.js+jade抓取博客所有文章生成静态html文件的实例
2017/09/19 Javascript
详解layui弹窗父子窗口之间传参数的方法
2018/01/16 Javascript
详解微信小程序调用支付接口支付
2019/04/28 Javascript
对node通过fs模块判断文件是否是文件夹的实例讲解
2019/06/10 Javascript
微信小程序用户授权弹窗 拒绝时引导用户重新授权实现
2019/07/29 Javascript
CentOS安装pillow报错的解决方法
2016/01/27 Python
Python每天必学之bytes字节
2016/01/28 Python
Python函数装饰器实现方法详解
2018/12/22 Python
django foreignkey(外键)的实现
2019/07/29 Python
Python基本语法之运算符功能与用法详解
2019/10/22 Python
德国前卫设计师时装在线商店:Luxury Loft
2019/11/04 全球购物
车辆转让协议书
2014/04/15 职场文书
高中运动会广播稿
2014/09/16 职场文书
国土资源局开展党的群众路线教育实践活动整改措施
2014/09/26 职场文书
2014年教研员工作总结
2014/12/23 职场文书
大学生个人学年总结
2015/02/15 职场文书
2015年医务科工作总结范文
2015/05/26 职场文书
使用nginx动态转换图片大小生成缩略图
2021/03/31 Servers
解决golang 关于全局变量的坑
2021/05/06 Golang
Python djanjo之csrf防跨站攻击实验过程
2021/05/14 Python
MySQL数据库10秒内插入百万条数据的实现
2021/11/01 MySQL
python使用opencv对图像添加噪声(高斯/椒盐/泊松/斑点)
2022/04/06 Python