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 相关文章推荐
IE6下focus与blur错乱的解决方案
Jul 31 Javascript
重写javascript中window.confirm的行为
Oct 21 Javascript
JS修改css样式style浅谈
May 06 Javascript
javascript图片预加载实例分析
Jul 16 Javascript
JavaScript实现将文本框的值插入指定位置的方法
Aug 13 Javascript
jquery常用的12个小功能
Jul 22 Javascript
微信小程序 教程之WXML
Oct 18 Javascript
jQuery实现可编辑表格并生成json结果(实例代码)
Jul 19 jQuery
浅谈ng-zorro使用心得
Dec 03 Javascript
详解Vue.js和layui日期控件冲突问题解决办法
Jul 25 Javascript
js 数组当前行添加数据方法详解
Jul 28 Javascript
vue的hash值原理也是table切换实例代码
Dec 14 Vue.js
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 日期时间函数的高级应用技巧
2009/10/10 PHP
php 静态变量与自定义常量的使用方法
2010/01/26 PHP
table标签的结构与合并单元格的实现方法
2013/07/24 PHP
PHP实现搜索相似图片
2015/09/22 PHP
php图片上传类 附调用方法
2016/05/15 PHP
php通过PHPExcel导入Excel表格到MySQL数据库的简单实例
2016/10/29 PHP
解决laravel上传图片之后,目录有图片,但是访问不到(404)的问题
2019/10/14 PHP
原生JS实现表单checkbook获取已选择的值
2013/07/21 Javascript
jQuery插件开发的五种形态小结
2015/03/04 Javascript
js实现点击向下展开的下拉菜单效果代码
2015/09/01 Javascript
JavaScript基础知识之方法汇总结
2016/01/24 Javascript
js实现String.Fomat的实例代码
2016/09/02 Javascript
微信小程序 连续旋转动画(this.animation.rotate)详解
2017/04/07 Javascript
JS中type="button"和type="submit"的区别
2017/07/04 Javascript
荐书|您有一份JavaScript书单待签收
2017/07/21 Javascript
Js判断H5上下滑动方向及滑动到顶部和底部判断的示例代码
2017/11/15 Javascript
基于jQuery实现Ajax验证用户名是否可用实例
2018/03/25 jQuery
使用vue-cli(vue脚手架)快速搭建项目的方法
2018/05/21 Javascript
Vue.js下拉菜单组件使用方法详解
2019/10/19 Javascript
Vue2.0 $set()的正确使用详解
2020/07/28 Javascript
Openlayers实现距离面积测量
2020/09/28 Javascript
python使用scrapy解析js示例
2014/01/23 Python
python操作摄像头截图实现远程监控的例子
2014/03/25 Python
Python使用分布式锁的代码演示示例
2018/07/30 Python
值得收藏的10道python 面试题
2019/04/15 Python
关于tf.nn.dynamic_rnn返回值详解
2020/01/20 Python
澳大利亚优质葡萄酒专家:Vintage Cellars
2019/01/08 全球购物
毕业生个人求职的自我评价
2013/10/28 职场文书
暑期培训随笔感言
2014/03/10 职场文书
公司爱心捐款倡议书
2014/05/14 职场文书
企业文化理念标语
2014/06/10 职场文书
2015年大学生党员承诺书
2015/04/27 职场文书
论文答辩开场白大全
2015/05/27 职场文书
2016年中学端午节主题活动总结
2016/04/01 职场文书
JavaScript原型链中函数和对象的理解
2022/06/16 Javascript
详解Spring Security如何在权限中使用通配符
2022/06/28 Java/Android