zoukankan      html  css  js  c++  java
  • bootstrap插件学习-bootstrap.button.js

    先看bootstrap.button.js的结构

    var Button = function ( element, options ){} //构造器
    Button.prototype = {} //构造器的原型
    $.fn.button = function ( option ){} //jQuery原型上的自定义方法
    $.fn.button.defaults = {} //默认参数
    $.fn.button.Constructor = Button //重写jQuery原型自定义方法的构造器名
    $(function (){}) // 初始化

    HTML结构

    <table class="table table-bordered table-striped">
        <tbody>
        <tr>
            <td>状态</td>
            <td><button id="fat-btn" class="btn btn-primary" data-loading-text="loading..."> 载入状态 </button></td>
        </tr>
        <tr>
            <td>单独开关</td>
            <td><button class="btn btn-primary" data-toggle="button">单独开关</button></td>
        </tr>
        <tr>
            <td>复选</td>
            <td>
                    <div class="btn-group" data-toggle="buttons-checkbox">
                    <button class="btn btn-primary"></button>
                    <button class="btn btn-primary"></button>
                    <button class="btn btn-primary"></button>
                </div>
            </td>
        </tr>
        <tr>
            <td>单选</td>
            <td>
                <div class="btn-group" data-toggle="buttons-radio">
                    <button class="btn btn-primary"></button>
                    <button class="btn btn-primary"></button>
                    <button class="btn btn-primary active"></button>
                </div>
            </td>
        </tr>
    
        </tbody>
    </table>

    这个例子有点问题,因为初始化时,第一个按钮没有绑定事件,所以第一个按钮不可用,不过没关系,读完源码之后,我们尝试将它补全。

    /*
      * 初始化
      * 这里初始化了拥有data-toggle^='button'属性的对象,注意^,只要存在button字符串就可以匹配成功。
      * */
      $(function () {
        $('body').on('click.button.data-api', '[data-toggle^=button]', function ( e ) {
          var $btn = $(e.target)
          if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
          $btn.button('toggle')//进入jQuery的原型方法button中
        })
      })

    像单独一个开关,直接本身就有btn类,像单选按钮,触发的是div里面的button,寻找最近的拥有.btn类的对象,就是自己。进入jQuery原型的button方法中。

    /*
      * jQuery原型上的自定义方法
      * */
      $.fn.button = function ( option ) {
        return this.each(function () {
          var $this = $(this)
            , data = $this.data('button')
            , options = typeof option == 'object' && option
          if (!data) $this.data('button', (data = new Button(this, options)))//实例化构造器
          if (option == 'toggle') data.toggle() //执行toggle方法
          else if (option) data.setState(option)
        })
      }

    初始化,传入参数为toggle,默认执行原型上的toggle方法。先实例化

    /*
      * 构造器
      * */
      var Button = function ( element, options ) {
        this.$element = $(element)
        this.options = $.extend({}, $.fn.button.defaults, options)//合并默认参数
      }

    进入原型上的toggle方法

    toggle: function () {
            var $parent = this.$element.parent('[data-toggle="buttons-radio"]') //如果父节点有该属性,则表示只能允许
              //一个按钮显示被按效果
            /*
            * 跟之前总结的方式,先所有删除,最后那个点击那个显示效果
            * */
            $parent && $parent
              .find('.active')
              .removeClass('active')
    
            this.$element.toggleClass('active')//核心方法,通过active类样式控制btn的显示效果
          }

    核心竟是jQuery的toggleClass方法。。这里做了一个特例区分,如果父类有data-toggle='buttons-radio'属性的,只能有一个按钮有特殊样式,这个逻辑之前我们已经在别的插件中总结了。上述的代码也是用的这个逻辑。

    ok,回到我们开始的问题,第一个按钮不能使用,那是我们没有绑定事件,在我们动手做之前,先大致看一下原型上的另一个方法setState

    setState: function ( state ) {
            var d = 'disabled'
              , $el = this.$element
              , data = $el.data()
              , val = $el.is('input') ? 'val' : 'html'//如果是input,采用val()方取值,不是则使用html()方法
            state = state + 'Text'
            data.resetText || $el.data('resetText', $el[val]())
            //console.log(this.options[state]);
            $el[val](data[state] || this.options[state])
    
            // push to event loop to allow forms to submit
            setTimeout(function () {
              state == 'loadingText' ?
                $el.addClass(d).attr(d, d) :
                $el.removeClass(d).removeAttr(d);
            }, 0)
          }

    如果我们获取第一个按钮的jQuery对象,调用button方法,必须要传参数,不传的话,不执行。详情可以回看它的button方法的定义。

    else if (option) data.setState(option)//需要传值

    传什么值,随便传么,试一下不行,重新看setState方法。它将形参与字符串'Text'相加,最后将其作为属性名去查找对象值,再看看$el.data()里的内容(默认参数和HTML结构)

    <button id="fat-btn" class="btn btn-primary" data-loading-text="loading..."> 载入状态 </button>

    data中有个loadingText属性,注意这里需要用驼峰命名。那我们传入的值就为loading了。实验一下,完全可以。

    至于最后在setState方法中加入定时器,本人觉得写的很蛋疼。loading的过程,是等待服务器响应并将处理结果返回给浏览器,一般考虑ajax实现,不过读者可以根据自己的需求,自行修改,没有最好的代码,只有更强的coder。

    上面的部分样式,大家可以参考bootstrap.css 去查看,比较简单。

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

  • 相关阅读:
    进阶算子
    Scala中sortBy和Spark中sortBy区别
    简单算子演示
    map和FlatMap之间区别?
    RDD
    Spark高可用
    Django Rest Framework
    Scrapy
    asyncio
    BeautifulSoup
  • 原文地址:https://www.cnblogs.com/wumadi/p/3272924.html
Copyright © 2011-2022 走看看