2.4.3 通用技术

根据上述JavaScript插件的实现步骤,来总结一下JavaScript插件的通用技术,即Bootstrap的开发者在开发这些插件时所制定的规则和遵循的标准,同时也为我们制作自定义插件提供有力的参考。

首先,不同插件的JS代码都是单独放在一个JS文件中的,开发人员在使用的时候可以一次性编译到Bootstrap.js,也可以单独使用某一个或者多个JS插件文件。唯一需要注意的是:有些JS插件依赖于其他JS插件,所以不要遗漏了依赖引用。

Bootstrap所有的JavaScript插件都可以通过配置使用,即通过特定的HTML设置,而不需要任何JavaScript再次触发。但如果需要启用手动触发事件的行为,可以禁用默认的行为,禁用方法非常简单,只需要将body元素上的命名空间为data-api下的全部事件禁用即可。代码如下所示:

  1. $(document).off('.data-api');

如果想禁用特定插件的默认行为,只需要禁用该插件所在命名空间下的事件即可。代码如下所示:

  1. $(document).off('.alert.data-api'); /* 禁用alert插件的所有默认行为 */

注意

off语法是jQuery提供的语法功能,用户在使用on进行绑定事件的时候,可以加命名空间,比如$().on('click.alert.data-api'),这样在卸载事件的时候,如果只想卸载该元素的该特定事件,可以使用off('click.alert.data-api')。如果不这样,仅仅使用off('click'),这样该元素上的所有click事件都将被卸载(导致该元素的其他click事件失效)。同理,如果执行off('.data-api')代码,则所有在data-api命名空间下的事件都会被卸载禁用,不管是该选择器内部的哪个元素、哪种事件。

1.可编程性

所有的插件不仅可以使用声明式定义(HTML),也可以通过JavaScript代码全部实现。利用jQuery的链式操作,编出的代码非常优美。示例如下所示:

  1. $(".btn.btn-danger").button("toggle").addClass("fat");

所有的插件在使用JavaScript代码调用的时候,都提供多种调用方式:无参数传递(即默认方式)、传递对象字面量进行初始化参数设定、直接传入一个需要执行的方法名称字符串。示例如下所示:

  1. $("#myModal").modal() // 默认值进行初始化
  2. $("#myModal").modal({ keyboard: false }) // 初始化时keyboard选项值是false
  3. $("#myModal").modal('show') // 初始化,然后立即调用show方法

每个插件都有一个Constructor属性,用于表示原始的构造函数,比如$.fn.alert.Constructor。另外也可以通过$('选择符').data('bs.插件名称')的形式(如,$('[data-dismiss="alert"]').data('bs.alert'))获取该特定插件的实例。

2.防冲突

和jQuery一样,Bootstrap插件可以和其他同类插件共存,为了防止$.fn.下的Bootstrap插件被覆盖,Bootstrap也提供了防冲突功能(No conflict),用于定义别名。示例用法如下:

  1. var bootstrapButton = $.fn.button.noConflict()
  2. // 返回$.fn.button对象给bootstrapButton变量
  3.  
  4. $.fn.bootstrapBtn = bootstrapButton
  5. // 将button对象给bootstrapButton变量赋予一个新插件名称$().bootstrapBtn,这时$().
  6. // bootstrapBtn就拥有了先前button的所有功能了

3.自定义事件

Bootstrap为很多插件都提供了自定义事件功能,比如,modal弹窗里提供的show和shown事件,show事件在弹窗初始化(即将弹出)的时候触发,而shown事件则是在弹窗初始化完毕后(完全弹出)才触发。

在新版插件里,所有的事件都是命名空间化的,即单个事件都要放在某个命名空间下,比如,show.bs.modal。

所有的插件都提供了preventDefault功能,用于阻止继续执行后续的代码。例如,可以在modal弹窗的show事件里进行判断,如果不符合条件就拒绝显示弹窗。示例代码如下所示:

  1. $('#myModal').on('show.bs.modal', function (e) {
  2. if (!data) return e.preventDefault() // 拒绝显示弹窗
  3. })