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 相关文章推荐
ASP.NET jQuery 实例6 (实现CheckBoxList成员全选或全取消)
Jan 13 Javascript
如何用ajax来创建一个XMLHttpRequest对象
Dec 10 Javascript
解决js正则匹配换行问题实现代码
Dec 10 Javascript
淘宝网提供的国内NPM镜像简介和使用方法
Apr 17 Javascript
解决JS请求服务器gbk文件乱码的问题
Oct 16 Javascript
解决angular的$http.post()提交数据时后台接收不到参数值问题的方法
Dec 10 Javascript
JavaScript实现简单的tab选项卡切换
Jan 05 Javascript
jQuery validate插件submitHandler提交导致死循环解决方法
Jan 21 Javascript
详解Webwork中Action 调用的方法
Feb 02 Javascript
Angular中ng-repeat与ul li的多层嵌套重复问题
Jul 24 Javascript
jquery实现左右轮播图效果
Sep 28 jQuery
浅析JS中回调函数及用法
Jul 25 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
dedecms 批量提取第一张图片最为缩略图的代码(文章+软件)
2009/10/29 PHP
PHP安全性漫谈
2012/06/28 PHP
ThinkPHP之N方法实例详解
2014/06/20 PHP
CodeIgniter错误mysql_connect(): No such file or directory解决方法
2014/09/06 PHP
php导入模块文件分享
2015/03/17 PHP
php实现将HTML页面转换成word并且保存的方法
2016/10/14 PHP
使Ext的Template可以解析二层的json数据的方法
2007/12/22 Javascript
jQuery 判断页面元素是否存在的代码
2009/08/14 Javascript
MooBox 基于Mootools的对话框插件
2012/01/20 Javascript
一款jquery特效编写的大度宽屏焦点图切换特效的实例代码
2013/08/05 Javascript
解析prototype,JQuery中跳出each循环的方法
2013/12/12 Javascript
js使用html()或text()方法获取设置p标签的显示的值
2014/08/01 Javascript
用js代码和插件实现wordpress雪花飘落效果的四种方法
2014/12/15 Javascript
实例讲解js验证表单项是否为空的方法
2016/01/09 Javascript
基于ajax与msmq技术的消息推送功能实现代码
2016/12/26 Javascript
详解AngularJS中$filter过滤器使用(自定义过滤器)
2017/02/04 Javascript
javascript设计模式之单体模式学习笔记
2017/02/15 Javascript
JS组件系列之MVVM组件构建自己的Vue组件
2017/04/28 Javascript
jQuery实现百度图片移入移出内容提示框上下左右移动的效果
2018/06/05 jQuery
详解vue axios二次封装
2018/07/22 Javascript
Vue CLI3基础学习之pages构建多页应用
2019/06/02 Javascript
React冒泡和阻止冒泡的应用详解
2020/08/18 Javascript
解决Vue keep-alive 调用 $destory() 页面不再被缓存的情况
2020/10/30 Javascript
javascript实现倒计时提示框
2021/03/02 Javascript
[50:48]LGD vs CHAOS 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
Python 监测文件是否更新的方法
2019/06/10 Python
Python3内置模块random随机方法小结
2019/07/13 Python
Matplotlib scatter绘制散点图的方法实现
2020/01/02 Python
python代码如何实现余弦相似性计算
2020/02/09 Python
pytorch 查看cuda 版本方式
2020/06/23 Python
css3实现的多级渐变下拉菜单导航效果代码
2015/08/31 HTML / CSS
Jimmy Choo美国官网:周仰杰鞋子品牌
2018/06/08 全球购物
迪奥美国官网:Dior美国
2019/12/07 全球购物
工程主管竞聘书
2015/09/15 职场文书
Nginx使用Lua模块实现WAF的原理解析
2021/09/04 Servers
Python绘制散乱的点构成的图的方法
2022/04/21 Python