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 去查看,比較簡單。

內容不多,時間剛好,以上是我的一點讀碼體會,如有錯誤,請指出,大家共通學習。 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM