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 去查看,比较简单。

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

  • 相关阅读:
    Server Tomcat v8.0 Server at localhost was unable to start within 45 seconds. If the server requires more time, try increasing the timeout in the server editor.
    用户画像——“打标签”
    python replace函数替换无效问题
    python向mysql插入数据一直报TypeError: must be real number,not str
    《亿级用户下的新浪微博平台架构》读后感
    【2-10】标准 2 维表问题
    【2-8】集合划分问题(给定要分成几个集合)
    【2-7】集合划分问题
    【2-6】排列的字典序问题
    【2-5】有重复元素的排列问题
  • 原文地址:https://www.cnblogs.com/wumadi/p/3272924.html
Copyright © 2011-2022 走看看