iuap-design/blog

dropdown 源码解读

whizbz11 opened this issue · 0 comments

使用方式

引入文件

所需文件:
1、jquery.js
2、dropdown.js

代码引用

整个dropdown组件包裹在类为“dropdown”的容器里,内部有个‘dropdown-toggle’的a元素和样式为‘dropdown-menu’的ul元素。a元素是触发下拉菜单显示隐藏的toggle元素,ul元素是下拉菜单的内容

        <li class="dropdown">
            <a href="#" class="dropdown-toggle" data-toggle="dropdown">
               Java 
               <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
               <li><a href="#">jmeter</a></li>
               <li><a href="#">EJB</a></li>
               <li class="divider"></li>
               <li><a href="#">另一个分离的链接</a></li>
            </ul>
         </li>
        $(“. dropdown-toggle”).dropdown(‘toggle’)触发下拉菜单的展开或折叠

整理架构

整体**

通过data-toggle绑定触发事件的父集元素,点击添加或删除open样式类,由此展开或折叠下拉菜单;

构建dropdown类,当即触发click事件,调用dropdown.prototype.toggle方法,toggle发放中调用clearMenus函数折叠下拉框,下拉框折叠的情况触发if语句展开下拉框;

构造函数

         var backdrop = '.dropdown-backdrop'
      var toggle   = '[data-toggle="dropdown"]'
      var Dropdown = function (element) {
        $(element).on('click.bs.dropdown', this.toggle)
      }

      Dropdown.VERSION = '3.3.6'

          // 由触发元素dropdown-toggle调用dropdown方法,通过data属性new出一个dropdown实例,data属性也记录该对象,继而通过传入的option参数调用实例的toggle方法  
          function Plugin(option) {
        return this.each(function () {
          var $this = $(this)
          var data  = $this.data('bs.dropdown')

          if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
          if (typeof option == 'string') data[option].call($this)
        })
      }

      var old = $.fn.dropdown

      $.fn.dropdown             = Plugin
      $.fn.dropdown.Constructor = Dropdown

         // DROPDOWN NO CONFLICT
        // $.fn.dropdown已存在,使用old保存该值,$.fn.dropdown空闲出来完成操作,执行        $.fn.dropdown.noConflict回归原$.fn.dropdown  

      $.fn.dropdown.noConflict = function () {
        $.fn.dropdown = old
        return this
      }

事件

触发事件
  $(document)  
    .on('click.bs.dropdown.data-api', clearMenus)  //点击页面其他地方时,收起menu
    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })  //假如下拉菜单里有表单元素时,通过冒泡阻止菜单的隐藏
    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)  //自动注册dropdown组件
    .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)  //在toggle元素获取焦点后,允许按向下箭头展开菜单
    .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)  //允许在展开菜单后,可以通过向上向下箭头,切换菜单项
用户可自定义事件函数

包裹元素dropdown中设置show(展开前)、focus(展开中)、shown(展开后)、hide(隐藏前)、hidden(隐藏后)事件,show和hide事件中可以阻止默认事件发生。

菜单展开前的函数定义
$('#myDropdown').on('show.bs.dropdown', function () {
  // do something…
})

心得体会

  • 事件绑定方式
    平时写代码时,如果给某个按钮添加事件会这样写:
$('button').on("click", function (event) { 
    alert(1);
});

而bootstrap中将事件都绑定到了document上。

$(document).on('click.bs.btn','button',function (e){};

中间多了一个参数,而且选择器变成了document。它的好处是只在document上绑定一个单击事件,利用冒泡的机制,在单击的时候检查是否是button元素,如果是才处理。而不是每个button都绑定事件,性能会提高很多

  • 代码格式学习