• bootstrap插件学习-bootstrap.dropdown.js


    bootstrap插件学习-bootstrap.dropdown.js

    先看bootstrap.dropdown.js的结构

    复制代码
    var toggle = '[data-toggle="dropdown"]'//属性标记
    Dropdown = function(){} //构造器
    Dropdown.prototype = {} // 构造器的原型
    function clearMenus() // 自定义方法
    $.fn.dropdown = function ( option ){}//jQuery原型上的自定义方法
    $.fn.dropdown.Constructor = Dropdown //重写方法的构造函数名
    $(function(){}) //默认初始化执行
    复制代码

    HTML结构

    复制代码
    <ul class="nav nav-pills">
          <li><a href="#">规则的链接</a></li>
          <li class="dropdown" id="menutest1">
            <a class="dropdown-toggle" data-toggle="dropdown" href="#menutest1">
              下拉项
              <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
              <li><a href="#">动作</a></li>
              <li><a href="#">另一个动作</a></li>
              <li><a href="#">其他</a></li>
              <li class="divider"></li>
              <li><a href="#">被间隔的链接</a></li>
            </ul>
          </li>
          <li class='active'>
            <a data-toggle="dropdown" href="#menutest1">点击我看看</a>
          </li>
        </ul>
    复制代码

     从初始化即时函数开始

    复制代码
    /*
      * 默认初始化执行
      * 初始化时,给html和body分别加入监听事件click,html这触发clearMenus方法,body则让toggle对象触发Dropdown原型上的方法
      * */
      $(function () {
        $('html').on('click.dropdown.data-api', clearMenus)
        $('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle)
      })
    复制代码

    这里需要注意事件的冒泡,一般我们点击页面上的一个按钮(或者一个可见的标签时)时,现在你点击的这个标签上先触发事件,如果你这个标签上有事件的话,触发完之后,它会继续向上冒泡,到其父节点,看是否有绑定事件,接着依次向上冒泡,直到文档节点,拿上面的代码讲,我们如果点击了页面中的按钮,先是body上的事件触发,然后则是html上的事件触发。

    我们先从body的事件开始,body的监听事件绑定到拥有data-toggle='dropdown'属性的标签上,根据HTML的结构,我们可以清楚的看到有两个标签拥有事件,下面进入该事件Dropdown原型上的toggle方法

    复制代码
    //构造器的原型
      Dropdown.prototype = {
    
        constructor: Dropdown
    
      , toggle: function ( e ) {
          var $this = $(this)
            , selector = $this.attr('data-target')
            , $parent
            , isActive;
          /*
          * 如果没有data-target属性,则使用a标签的href属性,根据正则取到其#和#以后的字符串,放入jQuery容器中,
          * 变为jQuery对象。
          * */
          if (!selector) {
            selector = $this.attr('href')
            selector = selector && selector.replace(/.*(?=#[^s]*$)/, '') //strip for ie7
          }
    
          $parent = $(selector)
          //console.log($parent);
    //如果没写,则自动去获取其父节点
    $parent.length || ($parent = $this.parent()) isActive = $parent.hasClass('open') clearMenus() /* * 如果li标签上没有open类则加上open类 * */ !isActive && $parent.toggleClass('open') return false//阻止冒泡 } }
    复制代码

    这里,方法先判断点击标签是否拥有data-target属性,如果没有则需要正则去解析href,两种方法的目的就是为了得到与这个标签相关联控制下拉框的li,为什么不直接找到下拉框信息的ul,原因在bootstrap.css里,在此之前,我们先进入clearMenus方法看一下。

    复制代码
      //自定义方法
        /*
        * 根据HTML结构,我们举例,$(toggle)为a标签的jQuery对象,
        * */
      function clearMenus() {
        $(toggle).parent().removeClass('open')//如果点击文档,则执行将li标签去除open类,其实这个open类也是个标记,我们可以利用,便于扩展
      }
    复制代码

    清除两个按钮的父节点的open类,这里的逻辑是这样的。

    如果页面有两个按钮控制下拉框显示和隐藏,先判断我们所点的按钮的父节点是否有open属性,然后清空所有按钮的父节点属性,然后在给所点按钮的父节点加上open属性。至于为啥呢么加上open就能达到效果,看bootstrap.css

    复制代码
    .dropdown-menu {
      position: absolute;
      top: 100%;
      left: 0;
      z-index: 1000;
      display: none;/*dropdown-menu开始为隐藏的*/
      float: left;
      min- 160px;
      padding: 5px 0;
      margin: 2px 0 0;
      list-style: none;
      background-color: #ffffff;
      border: 1px solid #ccc;
      border: 1px solid rgba(0, 0, 0, 0.2);
      *border-right- 2px;
      *border-bottom- 2px;
      -webkit-border-radius: 6px;
         -moz-border-radius: 6px;
              border-radius: 6px;
      -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
         -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
              box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
      -webkit-background-clip: padding-box;
         -moz-background-clip: padding;
              background-clip: padding-box;
    }
    
    .open {
      *z-index: 1000;
    }
    
    .open > .dropdown-menu {
      display: block;/*加入open类,之后变为显示*/
    }
    复制代码

    这种根据css规则去渲染页面,而不通过js查询style属性修改css样式,感觉前者的效率会更高一些。在bootstrap插件中,很多情况都是采用这种方式,到时候看到我们还需要留意。

    之后,你可以选择点击本身按钮(或者是其他按钮)关闭,或者点击文档关闭,都是可以的。两种方法本身都是执行了clearMenus方法。清除了open属性。

    内容不多,时间刚好,以上是我的一点读码体会,如有错误,请指出,大家共通学习。 

  • 相关阅读:
    新的开始
    react的setState使用中遇到的问题
    h5的input的required使用中遇到的问题
    vue学习中v-if和v-show一起使用的问题
    异步 JavaScript 之 macrotask、microtask
    .eslintrc 文件
    Vue2学习结合bootstrapTable遇到的问题
    Vue2学习(3)
    ES6 箭头函数
    Vue2学习(2)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3269885.html
Copyright © 2020-2023  润新知