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 相关文章推荐
使用SyntaxHighlighter实现HTML高亮显示代码的方法
Feb 04 Javascript
jquery实现心算练习代码
Dec 06 Javascript
JS this作用域以及GET传输值过长的问题解决方法
Aug 06 Javascript
jQuery实现精美的多级下拉菜单特效
Mar 14 Javascript
jquery实现可点击伸缩与展开的菜单效果代码
Aug 31 Javascript
Bootstrap Table服务器分页与在线编辑应用总结
Aug 08 Javascript
AngularJS表单基本操作
Jan 09 Javascript
babel基本使用详解
Feb 17 Javascript
Node.js 中exports 和 module.exports 的区别
Mar 14 Javascript
JS实现的按钮点击颜色切换功能示例
Oct 19 Javascript
swiper自定义分页器使用方法详解
Sep 14 Javascript
vue 子组件和父组件传值的示例
Sep 11 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函数
2006/12/06 PHP
ThinkPHP实现跨模块调用操作方法概述
2014/06/20 PHP
PHP使用php-resque库配合Redis实现MQ消息队列的教程
2016/06/29 PHP
Thinkphp5框架异常处理操作实例分析
2020/06/03 PHP
静态页面的值传递(三部曲)
2006/09/25 Javascript
js下利用控制器载入对应脚本
2010/07/17 Javascript
浅析Javascript使用include/require
2013/11/13 Javascript
深入分析escape()、encodeURI()、encodeURIComponent()的区别及示例
2014/08/04 Javascript
js实现仿QQ秀换装效果的方法
2015/03/04 Javascript
js+html5实现可在手机上玩的拼图游戏
2015/07/17 Javascript
AngularJS使用带属性值的ng-app指令实现自定义模块自动加载的方法
2017/01/04 Javascript
JavaScript编写九九乘法表(两种任选)
2017/02/04 Javascript
借助node实战JSONP跨域实例
2017/03/30 Javascript
基于Node的React图片上传组件实现实例代码
2017/05/10 Javascript
Vue.js用法详解
2017/11/13 Javascript
JavaScript设计模式之缓存代理模式原理与简单用法示例
2018/08/07 Javascript
js绘制一条直线并旋转45度
2020/08/21 Javascript
[04:09]2018年度DOTA2社区贡献奖-完美盛典
2018/12/16 DOTA
Python实现嵌套列表及字典并按某一元素去重复功能示例
2017/11/30 Python
解决Mac安装scrapy失败的问题
2018/06/13 Python
python获取命令行输入参数列表的实例代码
2018/06/23 Python
Python实现连接MySql数据库及增删改查操作详解
2019/04/16 Python
python实现人机五子棋
2020/03/25 Python
jupyter notebook指定启动目录的方法
2021/03/02 Python
html5版canvas自由拼图实例
2014/10/15 HTML / CSS
HealthElement海外旗舰店:新西兰大卖场
2018/02/23 全球购物
加热夹克:RAVEAN
2018/10/19 全球购物
英国最大的在线亚洲杂货店:Red Rickshaw
2020/03/22 全球购物
阿迪达斯中国官网:Adidas中国
2020/12/14 全球购物
北京银河万佳Java面试题
2012/03/21 面试题
linux面试题参考答案(1)
2016/01/22 面试题
同事吵架检讨书
2014/02/05 职场文书
企业安全生产承诺书
2014/05/22 职场文书
科学发展观活动总结
2014/08/28 职场文书
党员四风自我剖析材料思想汇报
2014/09/13 职场文书
课程设计感想范文
2015/08/11 职场文书