bootstrap源碼學習與示例:bootstrap-collapse


這次說的是手風琴組件,但是bootstrap的實現有點奇怪,CSS中的類名以accordion為前綴,JS里面的處理組件與相關方法為collapse。

HTML結構以下:類名accordion的DIV包含N個類名為accordion-group的DIV,每組又分兩部分accordion-heading與accordion-body。accordion-heading包含觸發用的accordion-toggle,accordion-body里的accordion-inner才是用於放內容的。

       <div class="accordion" id="accordion2">
            <div class="accordion-group">
              <div class="accordion-heading">
                <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#collapseOne">
                  國土問題
                </a>
              </div>
              <div id="collapseOne" class="accordion-body collapse" style="height: 0px;">
                <div class="accordion-inner">
		  前一段時間一個段子說,某國的網民在因國土問題與中國網民爭吵時說,我要打到北京,中國的網民非常淡然地回應,就你那經濟水平,交得起過路費嗎?這兩天新的段子說,李白要是活在今天的話,估計一大半以上他的詩根本寫不出來,因為名山大川的門票他根本買不起。
                </div>
              </div>
            </div>
            <div class="accordion-group">
              <div class="accordion-heading">
                <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#collapseTwo">
                  門票問題
                </a>
              </div>
              <div id="collapseTwo" class="accordion-body collapse" style="height: 0px;">
                <div class="accordion-inner">
		  目前,中國半數5A級景區門票達到100元,黃山門票10年來由80元漲至230元。山東曲阜稱,與同類景區相比收費較低,僅收150元,不漲票價就丟身價。曲阜的孔廟、孔府和孔林,年收入1.5億元左右,全部上繳了地方財政,但景區維護成本從未公開。
                </div>
              </div>
            </div>
            <div class="accordion-group">
              <div class="accordion-heading">
                <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#collapseThree">
                  超生罰款
                </a>
              </div>
              <div id="collapseThree" class="accordion-body in" style="height: auto;">
                <div class="accordion-inner">
		  學者楊支柱因生二胎被取消公職,並罰款24萬余元。他稱,計生罰款以前直接叫超生罰款,入世后改成“社會撫養費”。根據9省市超生罰款的平均數,全國31個省市每年征收的超生罰款可高達279億元。其中大城市將該收入上繳財政,而地方則分配混亂,部分罰款去向成謎。
                </div>
              </div>
            </div>
          </div>

與其他組件一樣,只要引用它就能使用了。但綁定回調時,要綁定.accordion-body之上。感覺bootstrap的官方教程做得不太好,沒有統一要綁定事件的類名,讓人一看就知道綁在那里。不過要用戶寫HTML感覺不太好。

!function ($) {

    "use strict"; // jshint ;_;


    /* COLLAPSE PUBLIC CLASS DEFINITION
  * ================================ */

    var Collapse = function (element, options) {
        this.$element = $(element)//對應 accordion-body
        this.options = $.extend({}, $.fn.collapse.defaults, options)

        if (this.options.parent) {
            this.$parent = $(this.options.parent)
        }

        this.options.toggle && this.toggle()
    }

    Collapse.prototype = {

        constructor: Collapse

        ,
        dimension: function () {
            var hasWidth = this.$element.hasClass('width')
            return hasWidth ? 'width' : 'height'
        }

        ,
        show: function () {
            var dimension
            , scroll
            , actives
            , hasData

            if (this.transitioning) return

            dimension = this.dimension()
            //如果沒有指明width類名
            scroll = $.camelCase(['scroll', dimension].join('-'))//求得scrollWidth 或scrollHeight
            //找到這個手風琴組件的所有展開的面板
            actives = this.$parent && this.$parent.find('> .accordion-group > .in')
            //然后合上它們
            if (actives && actives.length) {
                hasData = actives.data('collapse')
                if (hasData && hasData.transitioning) return
                actives.collapse('hide')//合上它們,並削去它們的實例
                hasData || actives.data('collapse', null)
            }
            //讓當前面板的高度或寬度為零
            this.$element[dimension](0)
            //開始動畫與觸發事件
            this.transition('addClass', $.Event('show'), 'shown')

            $.support.transition && this.$element[dimension](this.$element[0][scroll])
        }

        ,
        hide: function () {
            var dimension
            if (this.transitioning) return
            dimension = this.dimension()
            this.reset(this.$element[dimension]())
            this.transition('removeClass', $.Event('hide'), 'hidden')
            this.$element[dimension](0)
        }

        ,
        reset: function (size) {
            var dimension = this.dimension()

            this.$element
            .removeClass('collapse')
            [dimension](size || 'auto')//還原為原來的大小
            [0].offsetWidth

            this.$element[size !== null ? 'addClass' : 'removeClass']('collapse')

            return this
        }

        ,
        transition: function (method, startEvent, completeEvent) {
            var that = this
            , complete = function () {
                if (startEvent.type == 'show') that.reset()
                that.transitioning = 0
                that.$element.trigger(completeEvent)
            }

            this.$element.trigger(startEvent)

            if (startEvent.isDefaultPrevented()) return

            this.transitioning = 1
            //添加或移除類名in
            this.$element[method]('in')

            $.support.transition && this.$element.hasClass('collapse') ?
            this.$element.one($.support.transition.end, complete) :
            complete()
        }

        ,
        toggle: function () {//最重要的方法
            this[this.$element.hasClass('in') ? 'hide' : 'show']()
        }

    }


    /* COLLAPSE PLUGIN DEFINITION
  * ========================== */

    var old = $.fn.collapse

    $.fn.collapse = function (option) {
        return this.each(function () {
            var $this = $(this)
            , data = $this.data('collapse')
            , options = typeof option == 'object' && option
            if (!data) $this.data('collapse', (data = new Collapse(this, options)))
            if (typeof option == 'string') data[option]()
        })
    }

    $.fn.collapse.defaults = {
        toggle: true
    }

    $.fn.collapse.Constructor = Collapse


    /* COLLAPSE NO CONFLICT
  * ==================== */

    $.fn.collapse.noConflict = function () {
        $.fn.collapse = old
        return this
    }


    /* COLLAPSE DATA-API
  * ================= */

    $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) {
        var $this = $(this), href
        , target = $this.attr('data-target') //取得它要展開或折疊的區域,1通過'data-target'
        || e.preventDefault() //2通過href
        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
        , option = $(target).data('collapse') ? 'toggle' : $this.data()
        $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed')//?在CSS中沒有看到此類名
        $(target).collapse(option)//初始化手風琴 bootstrap有個特點,都是點擊時才開始初始化組件
    })

}(window.jQuery);

引入的less文件為accordion.less

bootstrap的手風琴只能以垂直形式出現。


免責聲明!

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



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