Fork me on GitHub

bootstrap-modal 学习笔记 源码分析

Bootstrap是Twitter推出的一个开源的用于前端开发的工具包,怎么用直接官网 http://twitter.github.io/bootstrap/

我博客的定位就是把这些年看过的源码给慢慢的总结出来,才疏学浅,不到位的见谅~

  • css部分呢Bootstrap由动态CSS语言Less写成,在很多方面类似CSS框架Blueprint
  • Bootstrap自带了13个jQuery插件,jquery这个东东,也是个版本帝,现在都10.1了…
  • 一直做移动app,都是用的自己的框架或者zepto,jquery就没正儿八经的用过,源码就看过1.42的后来改动太大了,具体慢慢分析看看源码吧

引入

<script src="src/jquery.js"></script>

<script src="src/bootstrap-transition.js"></script>

<script src="src/bootstrap-modal.js"></script>

<!-- Bootstrap -->

<link href="css/bootstrap.css" rel="stylesheet" media="screen">

 

   1:  <!-- Button to trigger modal -->
   2:  <a href="#myModal" role="button" class="btn" data-toggle="modal">查看演示案例</a>
   3:   
   4:  <!-- Modal -->
   5:  <div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
   6:      <div class="modal-header">
   7:          <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
   8:          <h3 id="myModalLabel">Modal header</h3>
   9:      </div>
  10:      <div class="modal-body">
  11:          <p>One fine body…</p>
  12:      </div>
  13:      <div class="modal-footer">
  14:          <button class="btn" data-dismiss="modal" aria-hidden="true">关闭</button>
  15:          <button class="btn btn-primary">Save changes</button>
  16:      </div>
  17:  </div>

 

从所周知,javascript 采用事件驱动(event-driven)。它是在用形界面的环境下,使得一切输入变化简单化。通常鼠标或热键的动作我们称之为事件(Event),而由鼠标或热键引发的一连串程序的动作,称之为事件驱动(Event Driver)。而对事件进行处理程序或函数,我们称之为事件处理程序(Event Handler)

Bootstrap是13个jquery插件,自然事件也是基于jquery处理的

我们先看看Bootstrap插件源码中常用的绑定机制

on方法

     jQuery1.7开始,jQuery引入了全新的事件绑定机制,on()和off()两个函数统一处理事件绑定 ,因为在此之前有bind(), live(), delegate()等方法来处理事件绑定,jQuery从性能优化以及方式统一方面考虑决定推出新的函数来统一事件绑定方法并且替换掉以前的方法,老版本还有live() 现在好像被废弃掉了,至于那个版本去掉的,我就没注意了

    简单的说下区别 :

  • bind 是一对一的
  • live 是指默认绑定到document,通过冒泡过滤
  • delegate 则是直接绑定指定的content,然后通过冒泡过滤

呵呵 考虑下 $('a').live() == $(document).delegate('a') ?

live废弃的原因,估计也是效率,然后不够灵活吧,尤其要提出来zepto的移动事件默认就绑定到document上,给项目带来不便……

on的处理机制也很简单,

看官方给的API的一个demo

   1:  <p>Click me!</p>
   2:  <span></span>
   3:   
   4:  <script>
   5:      var count = 0;
   6:      $("body").on("click", "p", function(){
   7:        $(this).after("<p>Another paragraph! "+(++count)+"</p>");
   8:      });
   9:  </script>

给body绑定一个点击事件, p元素可以响应,绑定事件的元素跟响应事件的元素其实不是同一个dom


 

将click事件绑定在body对象上,页面上任何元素发生的click事件都冒泡到document对象上得到处理,发现捕获到p元素就执行了代码了

on最终还是用   jQuery.event.add( this, types, fn, data, selector ); 为元素elem添加类型types的句柄handler,事实上所有的事件绑定最后都通过jQuery.event.add来实现。其执行过程大致如下: 

  1. 先调用jQuery._data从$.cache中取出已有的事件缓存如果是第一次在DOM元素上绑定该类型事件句柄,在DOM元素上绑定jQuery.event.handle,作为统一的事件响应入口 
  2. 将封装后的事件句柄放入缓存中 
  3. 传入的事件句柄,会被封装到对象handleObj的handle属性上,此外handleObj还会填充guid、type、namespace、data属性;DOM事件句柄elemData.handle指向jQuery.event.handle,即jQuery在DOM元素上绑定事件时总是绑定同样的DOM事件句柄jQuery.event.handle。 
  4. 事件句柄在缓存$.cache中的数据结构如下,事件类型和事件句柄都存储在属性events中,属性handle存放的执行这些事件句柄的DOM事件句柄

 

来看正文:

bootstrap-modal.js中 240行

   1:    $target
   2:          .modal(option)
   3:          .one('hide', function() {
   4:          $this.focus()
   5:        })

就是具体的执行调用了

Modal是一个很标准的js类的写法

通过$.fn.modal 扩展到了jquery的原型上了,返回this引用从而实现链式了

jquery是数组形式,所以扩展的时候需要 this.each


看看Modal提供的API

属性:

backdrop :包括一个模态的背景元素

keyboard:按退出键关掉模态对话框

show: 是否初始化就显示模态

remote:如果是远程地址,用jquery加载内容注入

方法

.modal(options)

让你指定的内容变成一个模态对话框。接受一个可选的参数object.

   1:  $('#myModal').modal({  keyboard: false})

.modal('toggle')

手动打开或隐藏一个模态对话框。

   1:  $('#myModal').modal('toggle')

.modal('show')

手动打开一个模态对话框。

   1:  $('#myModal').modal('show')

.modal('hide')

手动隐藏一个模态对话框。

   1:  $('#myModal').modal('hide')

 

   1:    $.fn.modal = function(option) {
   2:      return this.each(function() {
   3:        var $this = $(this),
   4:          data = $this.data('modal'),
   5:          options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
   6:          if (!data) $this.data('modal', (data = new Modal(this, options)))
   7:          if (typeof option == 'string') data[option]()
   8:          else if (options.show) data.show()
   9:      })
  10:    }

构建的代码被包装过

posted on 2013-06-28 14:53  【艾伦】  阅读(55911)  评论(4编辑  收藏  举报