Bootstrap 源码解析(转载苏青)

1、Bootstrap的作用域

2、Bootstrap的类定义

3、Bootstrap的插件定义

4、Bootstrap的事件代理

5、Bootstrap的对象数据缓存

6、Bootstrap的防冲突

7、作用域外如何使用Button类

8、Bootstrap的单元测试

Bootstrap的作用域

Bootstrap每个插件都定义在下面这段作用域代码中:

$(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) { 
 ... 
})
$(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) {
    ...    
})

这段JavaScript代码将click委托事件监听器绑定在document元素上,并给click事件赋予命名空间click.bs.button.data-api,选择器匹配的是属性data-toggle的值为"button"开头的标签。

关于jQuery将事件绑定在document文档对象上的好处,就是js事件代理的优点,性能上做了一个测试比较

关于jQuery命名空间的好处,请参看《jQuery .on() and .off() 命名空间》

Bootstrap的防止冲突

jQuery是全局对象,所以jQuery的插件定义$.fn.button并不受作用域限制。如果在别的插件中同样定义了button插件,后加载的button插件将会覆盖先加载的button插件,jsbin示例

var Cat = function(name) { 
 this.name = name 
} 
var cat1 = new Cat('Hello Kitty') 
var cat2 = new Cat('Doramon') 


cat1.constructor == Cat.prototype.constructor
var Cat = function(name) {
   this.name = name
}
var cat1 = new Cat('Hello Kitty')
var cat2 = new Cat('Doramon')

cat1.constructor == Cat.prototype.constructor

但是Javascript是区分大小写的,也就是 这里大写开头的的Constructor 和 Javascript小写开头的constructor 没有任何关系。

查找jQuery源码中也没有对于大写开头的Constructor的定义。所以这里的Constructor只是一个普通属性,我们也可以写成其他名字 $.fn.button.Something = Button,Bootstrap为了指明这个属性的意义而命名为构造器“Constructor”更合理。

这样一来,这段代码就很好理解了:$.fn.button.Constructor = Button 通过将闭包内的Button类赋值给jQuery的button对象的Constructor属性,在IIFE闭包外也可以使用Button类。调用方式:

Js代码 Bootstrap 源码解析(转载苏青)Bootstrap 源码解析(转载苏青)Bootstrap 源码解析(转载苏青)
  1. +function($){
  2. // 类定义
  3. var Button = function() {}
  4. // 插件定义
  5. $.fn.button = function() {
  6. alert('Bootstrap button')
  7. }
  8. // 类赋值到jQuery button对象的Constructor属性
  9. $.fn.button.Constructor = Button
  10. }(window.jQuery)
  11. var Button = $.fn.button.Constructor
+function($){
  // 类定义
  var Button = function() {}
  // 插件定义
  $.fn.button = function() {
      alert('Bootstrap button')
  }
  // 类赋值到jQuery button对象的Constructor属性
  $.fn.button.Constructor = Button

}(window.jQuery) 

var Button = $.fn.button.Constructor

Bootstrap的对象数据缓存

Js代码 Bootstrap 源码解析(转载苏青)Bootstrap 源码解析(转载苏青)Bootstrap 源码解析(转载苏青)
  1. // 获取存储的Button对象,如果是第一次执行变量data的值为undefined
  2. var data = $this.data('bs.button')
  3. var options = typeof option == 'object' && option
  4. // 创建Button对象: new Button(this, options),
  5. // 并赋值给变量data: data = new Button(this, options)
  6. // 存储在元素的jQuery对象上的‘bs.button’数据字段 $this.data('bs.button', data)
  7. if (!data) $this.data('bs.button', (data = new Button(this, options)))
  8. // data是一个Button对象,可以调用Button的原生方法
  9. if (option == 'toggle') data.toggle()
  10. elseif (option) data.setState(option)
// 获取存储的Button对象,如果是第一次执行变量data的值为undefined
var data    = $this.data('bs.button')
var options = typeof option == 'object' && option

// 创建Button对象: new Button(this, options),
// 并赋值给变量data: data = new Button(this, options)
// 存储在元素的jQuery对象上的‘bs.button’数据字段 $this.data('bs.button', data)
if (!data) $this.data('bs.button', (data = new Button(this, options)))

// data是一个Button对象,可以调用Button的原生方法
if (option == 'toggle') data.toggle()
else if (option) data.setState(option)

利用jQuery的 .data(key, value)存储Button对象

Bootstrap的单元测试

QUnit + PhantomJS

相关推荐