`

bootstrap-dropdown源码解读

 
阅读更多

1.插件的使用

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

$(“.        dropdown-toggle”).dropdown(‘toggle’)触发下拉菜单的展开或折叠;

  包裹元素的样式类是dropdown,触发元素的样式类是dropdown-toggle,下拉框元素的样式类是dropdown-menu。

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

 

<div 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><a href="#">Jasper Report</a></li>
       <li class="divider"></li>
       <li><a href="#">分离的链接</a></li>
       <li class="divider"></li>
       <li><a href="#">另一个分离的链接</a></li>
</ul>
</div>

 

2.整体架构

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

      构建$.fn.dropdown插件,data属性中new出一个dropdown类实现初始化,drop类初始化过程中绑定事件。

 

3.js和jquery的新认识

       函数中通过return以及状态改变、if条件前的数据记录使函数拥有不同的功能;

       $.event()为事件设置event-data数据,包括relatedTarget元素,trigger触发事件,on绑定函数,当事件触发执行绑定函数,通过绑定函数的方式使下拉框有效;

         event.isDefaultPrevented判断是否调用了preventDefault方法,使preventDefault()函数有效,event.preventDefault()阻止默认事件;

       event.stopPropagation()阻止事件冒泡,event.isPropagationStopped()判断有否调用stopPropagation方法。

 

function ($) {
  'use strict';

  // DROPDOWN CLASS DEFINITION
  // =========================

  // 触发元素和下拉元素为兄弟节点关系,[data-toggle="dropdown"]触发元素,dropdown-menu下拉框元素,dropdown包裹元素
  var backdrop = '.dropdown-backdrop'
  var toggle   = '[data-toggle="dropdown"]'
  // click.bs.dropdown事件在click事件的触发的时候也执行toggle函数,hide.bs.drop事件只能通过hide.bs.drop绑定,不能通过hide绑定
  var Dropdown = function (element) {
    $(element).on('click.bs.dropdown', this.toggle)
  }

  Dropdown.VERSION = '3.3.5'

  //通过data-target或者href获取包裹元素,不存在就选择父元素
  function getParent($this) {
    var selector = $this.attr('data-target')
    if (!selector) {
      selector = $this.attr('href')
      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
    }
    var $parent = selector && $(selector)
    return $parent && $parent.length ? $parent : $this.parent()
  }

  // clearMenus函数下拉框若为展开状态,就执行收起动作,折叠和展开通过添加open样式类实现
  // 通过return使函数具有多种用途,折叠状态不执行后续操作
  // trigger触发hide.bs.dropdown(折叠前)、hidden.bs.dropdown(折叠后)事件,on方法绑定函数,触发时间在clearMenus函数执行过程中
  // e.isDefaultPrevented()判断使hide事件中e.preventDefault()能阻止下拉框折叠、hidden事件触发,同样效果可以通过缓存实现
  function clearMenus(e) {
    if (e && e.which === 3) return //e.which哪个按钮或按键被点击
    $(backdrop).remove()
    $(toggle).each(function () {
      // dropdown方法被调用以外,还需要用[data-toggle="dropdown"]属性指向触发元素,查看该元素的属性填写情况是否合法
      var $this = $(this)
      var $parent = getParent($this)
      var relatedTarget = { relatedTarget: this }
      if (!$parent.hasClass('open')) return
      // 触发元素中包含input、textarea时跳出clearMenus函数
      if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
      // 父级元素触发hide事件,relatedTarget的目的是为mouseout、mouseleave指定相关元素/目标元素
      // $.event构建事件,可以配置数据以及relatedTarget关联元素,以便使用
      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
      // event.isDefaultPrevented判断是否调用了preventDefault方法,event.preventDefault()阻止默认事件
      // event.stopPropagation()阻止事件冒泡,event.isPropagationStopped()判断有否调用stopPropagation方法
      if (e.isDefaultPrevented()) return
      $this.attr('aria-expanded', 'false')
      $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget);
    })
  }

  // trigger触发show(展开前)、focus(展开中)、shown(展开后)事件
  // toggle通过单if语句实现折叠时展开,展开时折叠的效果,即顺序执行折叠,折叠前获取展开折叠状态,若为折叠if语句展开
  Dropdown.prototype.toggle = function (e) {
    // this指代调用dropdown方法的元素,clearMenus函数里再取填写[data-toggle="dropdown"]属性的元素,避免该属性未曾填写的元素
    var $this = $(this) 
    if ($this.is('.disabled, :disabled')) return
    var $parent  = getParent($this)
    var isActive = $parent.hasClass('open')
    clearMenus()
    if (!isActive) {
      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
        // 手机端使用backdrop,以使点击事件有效
        $(document.createElement('div'))
          .addClass('dropdown-backdrop')
          .insertAfter($(this))
          .on('click', clearMenus)
      }
      var relatedTarget = { relatedTarget: this }
      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
      if (e.isDefaultPrevented()) return
      $this
        .trigger('focus')
        .attr('aria-expanded', 'true')
      $parent
        .toggleClass('open')
        .trigger('shown.bs.dropdown', relatedTarget)
    }
    return false
  }

  // 下拉框以及触发元素处点击向上向下、空格Esc箭头通过trigger触发相应事件,
  Dropdown.prototype.keydown = function (e) {
    // 向上38、向下40、空格32、Esc键27
    if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
    var $this = $(this)
    e.preventDefault()
    e.stopPropagation()
    if ($this.is('.disabled, :disabled')) return
    var $parent  = getParent($this)
    var isActive = $parent.hasClass('open')
    // 触发元素折叠时按键触发点击事件,e.target也随之改变,以便上下箭头在下拉框中选择,展开时Esc按键触发focus事件折叠
    if (!isActive && e.which != 27 || isActive && e.which == 27) {
      if (e.which == 27) $parent.find(toggle).trigger('focus')
      return $this.trigger('click')
    }
    // 展开时下拉框向上向下箭头得到焦点
    var desc = ' li:not(.disabled):visible a'
    var $items = $parent.find('.dropdown-menu' + desc)
    if (!$items.length) return
    var index = $items.index(e.target)
    if (e.which == 38 && index > 0)                 index--         // up
    if (e.which == 40 && index < $items.length - 1) index++         // down
    if (!~index)                                    index = 0
    $items.eq(index).trigger('focus')
  }

  // DROPDOWN PLUGIN DEFINITION
  // ==========================

  // 由触发元素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

  // $.fn.dropdown已存在,使用old保存该值,$.fn.dropdown空闲出来完成操作,执行$.fn.dropdown.noConflict回归原$.fn.dropdown
  $.fn.dropdown.noConflict = function () {
    $.fn.dropdown = old
    return this
  }

  // APPLY TO STANDARD DROPDOWN ELEMENTS
  // ===================================

  // 点击[data-toggle="dropdown"]元素触发toggle方法,toggle方法中调用clearMenus函数先折叠,回到toggle再展开,点击其他区域折叠
  $(document)
    .on('click.bs.dropdown.data-api', clearMenus)
    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
    .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
    .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)

}(jQuery);

 

0
1
分享到:
评论

相关推荐

    bootstrap-dropdown.js

    "bootstrap-dropdown.js" 是Bootstrap框架中的一个重要组件,它主要用于实现下拉菜单功能。在Bootstrap的JavaScript插件集合中,dropdown组件使得在网页上创建交互式的下拉菜单变得简单易行。 在Bootstrap框架中,...

    bootstrap-hover-dropdown.min.js 2.2.1

    bootstrap-hover-dropdown.min.js 2.2.1,插件,实现hover下拉菜单

    BOOTSTRAP-TABLE源码

    BOOTSTRAP-TABLE是一款基于Bootstrap框架的开源前端数据展示插件,它允许用户在网页上创建功能丰富的表格,包括排序、筛选、分页等。这个源码包包含了官方的最新版本,适合开发者进行二次开发或者深入理解其工作原理...

    swagger-bootstrap-ui-1.9.6-API文档-中文版.zip

    赠送jar包:swagger-bootstrap-ui-1.9.6.jar; 赠送原API文档:swagger-bootstrap-ui-1.9.6-javadoc.jar; 赠送源代码:swagger-bootstrap-ui-1.9.6-sources.jar; 赠送Maven依赖信息文件:swagger-bootstrap-ui-...

    bootstrap-table可编辑下拉框editable js及css及bootstrap-table-editable.js以及使用实例

    这些文件通常包括Bootstrap的核心库、jQuery、bootstrap-table主文件,以及bootstrap-table-editable.js。确保这些资源被正确地链接或导入到HTML文档的`&lt;head&gt;`部分,以便在页面加载时可以正常使用。 以下是一个...

    bootstrap-editable.zip

    可编辑bootstrap-table及相关组件:bootstrap3、bootstrap-table相关、bootstrap-table-editable.js、bootstrap-editable.js、bootstrap-editable.css; 配合起来,可以实现可编辑bootstrap-table列表。代码实现: ...

    bootstrap-table实现 行拖拽 插件jquery.tablednd.js bootstrap-table-reorder-rows.js

    bootstrap-table实现 行拖拽 插件 jquery.tablednd.js bootstrap-table-reorder-rows.js bootstrap-table-reorder-rows.css

    bootstrap-datepicker-1.9.0_bootstrap源码_

    在本资源中,我们关注的是`bootstrap-datepicker-1.9.0`,这是一个针对Bootstrap框架的日期选择器插件。这个插件允许用户以美观、易用的方式选择日期,常见于各种表单输入和日历应用。 Bootstrap Datepicker是基于...

    bootstrap-table-editable.js+bootstrap-editable.js+bootstrap-editable.css

    压缩包里面有: 1.bootstrap-table-editable.js 2.bootstrap-editable.js 3.bootstrap-editable.css 用于bootstrap table实现x-editable的行单元格编辑

    bootstrap-dropdown-hover:基于Bootstrap的响应式多级下拉导航菜单,带有引人入胜的动画

    在本主题中,我们关注的是一个特定的Bootstrap扩展插件——`bootstrap-dropdown-hover`,它是一个响应式的多级下拉导航菜单,具有吸引人的动画效果。 这个插件的主要目的是改善Bootstrap默认的下拉菜单体验。在...

    bootstrap-table-pagejump.zip

    本篇文章将详细介绍`bootstrap-table-pagejump`的原理、使用方法以及源码分析。 一、插件介绍 `bootstrap-table-pagejump`插件是针对Bootstrap Table的增强,它添加了一个页面输入框,用户可以输入想要跳转的页码...

    前端项目-bootstrap-hover-dropdown.zip

    1. `dist/css/bootstrap-hover-dropdown.css`:这是插件的CSS文件,包含了必要的样式以实现悬停激活下拉菜单的功能。 2. `dist/js/bootstrap-hover-dropdown.js`:JavaScript文件,实现了悬停激活的逻辑。 3. `dist/...

    bootstrap-table-export.js bootstrap-table表格导出js

    bootstrap-table-export.js bootstrap-table表格导出js

    BootStrap-table.js 官网下载

    在"bootstarp-table.js"的官网下载中,我们通常会得到一个名为"bootstrap-table-master"的压缩包,这是项目的源码仓库,包含了完整的开发和编译资源。 Bootstrap-table.js 的主要特点包括: 1. **数据源绑定**:它...

    bootstrap-datetimepicker-简单好用的日历时间插件

    bootstrap-datetimepicker是一个简单好用的日历时间插件,在bootstrap首页上也有推荐。使用起来也很简单: 1,必须引入Jquery文件。 2,引入日历插件JS代码:bootstrap-datetimepicker.min.js 3,如果需要使用非英文...

    bootstrap-table-fixed-columns(css,js)

    这个项目的扩展`bootstrap-table-fixed-columns`专注于解决在大表格中固定首列或首行的问题,使得在滚动时这些重要列始终保持可见,提高用户在浏览长表格时的可读性和交互性。在网页设计中,尤其是在数据密集型应用...

    bootstrap-table-fixed-columns-v1.0.2.zip

    FastAdmin使用bootstrap-table作为前端表格的基础组件库,通常列表交互展示已经够用了,包括通用搜索、排序、分页、导出、合并相同行/列等等。最近需要对表头进行冻结,找到了bootstrap-table-fixed-columns组件(也...

    bootstrap-table后端分页功能完整实例

    本文实例讲述了bootstrap-table后端分页功能。分享给大家供大家参考,具体如下: 使用bootstrap-table实现后台分页 插件资源点击此处本站下载。 引用以下css &lt;link rel="stylesheet" href="../plugins/...

    bootstrap-table-editable.js/css

    压缩包里面有: 1.bootstrap-table-editable.js 2.bootstrap-editable.js 3.bootstrap-editable.css 用于bootstrap table实现x-editable的行单元格编辑

Global site tag (gtag.js) - Google Analytics