js插件实现步骤

Bootstrap里提供的所有JavaScript插件都遵守了统一的实现步骤,好处自然就不用多说了,除了维护方便以外,学习和自定义其他插件也都很方便。要做到统一,需要有5个步骤,如图2-16所示。
加载中...
 

下面以alert插件为例(alert.js),来讲述一下如何实现标准的插件。

步骤1 定义一个立即调用的函数声明,如代码清单2-1所示。在参数里传入jQuery对象,通过参数$引入变量,这样其所有代码在使用jQuery的时候,直接使用$符即可。这样的做法,有以下两个好处:

函数内部的$符变量代表了局部变量,而不是全局变量里代表jQuery的$符变量,以达到防止变量污染的目的。

内部的代码全部都是私有代码,外部代码无法访问,只有通过第三步,在$.fn上设置了插件(比如$.fn.alert=)的形式,通过$符变量才能将整个插件通过唯一的接口$.fn.alert暴露出去,从而保护了其内部代码。

代码清单2-1 立即调用的函数
+function ($) {
    "use strict";// 1.使用严格模式ES5支持
    // 2.alert插件类及原型方法的定义
    // 3.在jQuery上定义alert插件,并重设插件构造器
    //  重设插件构造器,可以通过该属性获取插件的真实类函数
    // 4. 防冲突处理
    // 5. 绑定触发事件
}(window.jQuery);

 注意

在function关键字前面有一个加号运算符(+),其主要目的是防止前面有未正常结束的代码(通常是遗漏了分号),导致前后代码被编译器认为是一体的,从而导致代码运行出错。

步骤2 定义该插件的核心代码,也就是在触发特定行为(通常是单击行为)后要进行处理的代码。示例如代码清单2-2所示。

代码清单2-2 插件核心代码示例
// alert插件类及原型方法的定义
// 定义选择器,所有符合该自定义属性的元素都可以触发下面的事件
var dismiss = '[data-dismiss="alert"]'
var Alert = function (el) {
    // 传入元素,如果元素内部有dismiss上设置的自定义属性,则click事件会触发原型上的close方法
    $(el).on('click', dismiss, this.close)
}
Alert.prototype.close = function (e) {
    // 关闭警告框的主要代码设置,每一行代码的细节注释,请参考5.8节
}

通过上述代码可以看出,主要是先定义了插件插件的类函数Alert,然后再定义需要用到的一些原型函数,比如close函数方法。Alert函数接收el参数,el表示DOM元素,一个DOM如果绑定了data-dismiss="alert"自定义属性,则在单击的时候就会触发close函数方法,从而达到关闭的目的。同样,Modal插件也是先定义Modal类函数,然后再在Modal的原型上定义toggle和show等方法,其内部根据相应的规则再细化处理。

步骤3 在jQuery上定义插件,以便通过jQuery.[插件名称]()的方式,也能够使用该插件,也就是在触发特定行为(通常是单击行为)后要进行处理的通用代码。最后在这里再调用插件类或原型方法。主要源码如代码清单2-3所示。

代码清单2-3 jQuery插件定义
// 在jQuery上定义alert插件,并重设插件构造器
var old = $.fn.alert
// 保留其他插件的$.fn.alert代码(如果定义),以便在noConflict之后,可以继续使用该旧代码
$.fn.alert = function (option) {
    return this.each(function () {
        // 根据选择器,遍历所有符合规则的元素,然后在元素上绑定插件的实例,以监控用户的事件行为
    })
}
$.fn.alert.Constructor = Alert;// 并重设插件构造器,可以通过该属性获取插件的真实类函数

jQuery插件的定义使用了标准的方法,在fn上进行扩展。在附加扩展之前,首先“备份”之前插件(或别的框架提供的同名插件)的旧代码,以方便在后面防冲突的时候使用。在附加扩展之后,重新设置插件的构造器(即Constructor属性)为内部定义的插件类函数自身,这样就可以通过Constructor属性查询到插件的真实类函数,使用new操作符实例化$.fn.alert的时候也不会出错。

 注意

即便不声明第三步,HTML声明式的方式也是可以用的。所以说,第三步是专门为某些喜欢用JavaScript代码触发事件的人所准备的。但需要注意的是,如果不声明第三步,那第四步的防冲突的功能也就没法用了。

步骤4 防冲突处理,目的是让Bootstrap插件和其他UI库的同名插件共存。Bootstrap所有的插件都支持防冲突(noConflict)功能。源码如代码清单2-4所示。

代码清单2-4 防冲突处理
// 防冲突处理
$.fn.alert.noConflict = function () {
    $.fn.alert = old // 恢复以前的旧代码
    return this  // 将$.fn.alert.noConflict()设置为Bootstrap的alert插件
}

这样一旦有了一个同名的插件,比如A库里有个同名$.fn.alert插件,则Bootstrap在执行之前就通过old先备份了,然后执行$.fn.alert.noConflict()后就会还原该old对象插件;而使用Bootstrap的alert插件的话,则通过var alert=$.fn.alert.noConflict()的形式,将Bootstrap的alert插件转移到另外一个变量上,从而进行使用。

步骤5 在一切都就绪之后,绑定默认的触发事件。由于已经为jQuery提供了默认的$.fn.alert扩展插件功能,已经可以通过手工编写JavaScript代码来触发事件了。这里的第五步主要是为声明式的HTML触发事件,即:在HTML文档里已经按照布局规则声明了相关的自定义属性(比如data-dismiss="alert"),然后通过这里的代码初始化默认的单击事件行为(或其他相关插件需要用到的行为)。绑定触发事件的源码如下所示:
// 绑定触发事件
// 为声明式的HTML绑定单击事件
// 在整个document对象上,检测是否有自定义属性data-dismiss="alert"
// 如果有,则设置:单击的时候,关闭指定的警告框元素
$(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)

上述代码在整个document文档上检测自定义属性data-dismiss="alert",如果有,则绑定click单击事件(在命名空间bs.alert.data-api上),事件回调函数则是原型方法Alert.prototype.close。这样,一旦单击了相应的元素,就会关闭特定的警告框。

Bootstrap通过这5个通用步骤,定义了所有的插件。每个插件在各个步骤里会有一些细节的不同,但思路都是一样的,那就是:绑定事件,触发行为,并在jQuery上扩展fn,同时解决防冲突的问题。大家在制作自定义插件的时候只要遵从这一思路,即可编写出既易于维护又高质量的插件代码。

你可能感兴趣的:(JavaScript点滴知识,javascript,插件步骤)