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 相关文章推荐
用Javascript实现Sleep暂停功能代码
Sep 03 Javascript
读jQuery之十三 添加事件和删除事件的核心方法
Aug 23 Javascript
jQuery实现文本展开收缩特效
Jun 03 Javascript
JavaScript判断对象是否为数组
Dec 22 Javascript
JavaScript实现设计模式中的单例模式的一些技巧总结
May 17 Javascript
javascript 广告移动特效的实现代码
Jun 25 Javascript
JavaScript之DOM_动力节点Java学院整理
Jul 03 Javascript
浅谈在vue项目中如何定义全局变量和全局函数
Oct 24 Javascript
解读vue生成的文件目录结构及说明
Nov 27 Javascript
layDate插件设置开始和结束时间
Nov 15 Javascript
jQuery利用FormData上传文件实现批量上传
Dec 04 jQuery
再也不怕 JavaScript 报错了,怎么看怎么处理都在这儿
Dec 09 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中数组的三种排序方法分享
2012/05/07 PHP
浅谈PHP安全防护之Web攻击
2017/01/03 PHP
YII框架学习笔记之命名空间、操作响应与视图操作示例
2019/04/30 PHP
PHP创建对象的六种方式实例总结
2019/06/27 PHP
JS获取IUSR_机器名和IWAM_机器名帐号的密码
2006/12/06 Javascript
分享十五个最佳jQuery 幻灯插件和教程
2010/03/27 Javascript
javascript cookies操作集合
2010/04/12 Javascript
将光标定位于输入框最右侧实现代码
2012/12/04 Javascript
JS定时器实例
2013/04/17 Javascript
封装的jquery翻页滚动(示例代码)
2013/11/18 Javascript
JavaScript中提前声明变量或函数例子
2014/11/12 Javascript
javascript实现动态标签云
2015/10/16 Javascript
jquery ui dialog替代confirm实例分析
2016/01/25 Javascript
微信小程序 富文本转文本实例详解
2016/10/24 Javascript
bootstrap中的 form表单属性role="form"的作用详解
2017/01/20 Javascript
jQuery Autocomplete简介_动力节点Java学院整理
2017/07/17 jQuery
AngularJS集合数据遍历显示的实例
2017/12/27 Javascript
在Vue组件上动态添加和删除属性方法
2018/02/23 Javascript
cropper js基于vue的图片裁剪上传功能的实现代码
2018/03/01 Javascript
JS实现字符串翻转的方法分析
2018/08/31 Javascript
webpack4手动搭建Vue开发环境实现todoList项目的方法
2019/05/16 Javascript
Vue 如何使用props、emit实现自定义双向绑定的实现
2020/06/05 Javascript
vue proxy 的优势与使用场景实现
2020/06/15 Javascript
python多线程方式执行多个bat代码
2016/06/07 Python
Windows下python3.6.4安装教程
2018/07/31 Python
python粘包问题及socket套接字编程详解
2019/06/29 Python
Python设计密码强度校验程序
2020/07/30 Python
canvas如何绘制钟表的方法
2017/12/13 HTML / CSS
Oracle中delete,truncate和drop的区别
2016/05/05 面试题
学习自我鉴定
2014/02/01 职场文书
师恩难忘教学反思
2014/04/27 职场文书
自荐信格式模板
2015/03/27 职场文书
2015年音乐教学工作总结
2015/07/22 职场文书
MySQL Shell的介绍以及安装
2021/04/24 MySQL
Win10服务全部禁用了怎么启动?Win10服务全部禁用解决方法
2022/09/23 数码科技
不想升级Win11?教你彻底锁定老版Windows系统的方法(附下载地址)
2022/09/23 数码科技