zoukankan      html  css  js  c++  java
  • bootrap 手风琴Collapse源码分析

    /* ========================================================================
     * Bootstrap: collapse.js v3.3.7
     * http://getbootstrap.com/javascript/#collapse
     * ========================================================================
     * Copyright 2011-2016 Twitter, Inc.
     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
     * ======================================================================== */
    
    /* jshint latedef: false */
    
    +function ($) {
      'use strict';
    
      // COLLAPSE PUBLIC CLASS DEFINITION
      // ================================
    
      var Collapse = function (element, options) {
        this.$element      = $(element)
        this.options       = $.extend({}, Collapse.DEFAULTS, options)
        this.$trigger      = $('[data-toggle="collapse"][href="#' + element.id + '"],' +//这是一个复合选择器   href  data-target双保险
                               '[data-toggle="collapse"][data-target="#' + element.id + '"]')
        this.transitioning = null
    
        if (this.options.parent) {
          this.$parent = this.getParent()//不仅返回了父元素而且还还把子元素的状态做了标记,比如谁是打开的。。。
        } else {
          this.addAriaAndCollapsedClass(this.$element, this.$trigger)
        }
    
        if (this.options.toggle) this.toggle()
      }
    
      Collapse.VERSION  = '3.3.7'
    
      Collapse.TRANSITION_DURATION = 350
    
      Collapse.DEFAULTS = {
        toggle: true
      }
    
      Collapse.prototype.dimension = function () {
        var hasWidth = this.$element.hasClass('width')
        return hasWidth ? 'width' : 'height'
      }
    
      Collapse.prototype.show = function () {
        if (this.transitioning || this.$element.hasClass('in')) return
    
        var activesData
        var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')//得到active的
    
        if (actives && actives.length) {
          activesData = actives.data('bs.collapse')
          if (activesData && activesData.transitioning) return
        }
    
        var startEvent = $.Event('show.bs.collapse')//在这里触发这个事件   (未显示之前)
        this.$element.trigger(startEvent)
        if (startEvent.isDefaultPrevented()) return
    
        if (actives && actives.length) {
          Plugin.call(actives, 'hide')//隐藏
          activesData || actives.data('bs.collapse', null)//activesData  没有的话,,,就设为null  ????
        }
    
        var dimension = this.dimension()
    
        this.$element
          .removeClass('collapse')
          .addClass('collapsing')[dimension](0)
          .attr('aria-expanded', true)
    
        this.$trigger
          .removeClass('collapsed')
          .attr('aria-expanded', true)
    
        this.transitioning = 1
    
        var complete = function () {
          this.$element
            .removeClass('collapsing')
            .addClass('collapse in')[dimension]('')
          this.transitioning = 0
          this.$element
            .trigger('shown.bs.collapse')
        }
    
        if (!$.support.transition) return complete.call(this)
    
        var scrollSize = $.camelCase(['scroll', dimension].join('-'))
    
        this.$element
          .one('bsTransitionEnd', $.proxy(complete, this))
          .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])//在最后通过取scrollHeight值,设置height(因为已经设置了css过度,)这里才是真正核心的功能,得到了隐藏元素的高度scrollHeight
      }
    
      Collapse.prototype.hide = function () {
        if (this.transitioning || !this.$element.hasClass('in')) return
    
        var startEvent = $.Event('hide.bs.collapse')
        this.$element.trigger(startEvent)
        if (startEvent.isDefaultPrevented()) return
    
        var dimension = this.dimension()
    
        this.$element[dimension](this.$element[dimension]())[0].offsetHeight//在style里面设置高度(为过度需要)
    
        this.$element
          .addClass('collapsing')//添加css过度类
          .removeClass('collapse in')
          .attr('aria-expanded', false)
    
        this.$trigger
          .addClass('collapsed')
          .attr('aria-expanded', false)
    
        this.transitioning = 1
    
        var complete = function () {//完成后调用的方法,处理收尾工作,1:把没有用的去掉,2:触发hidden.bs.collapse(隐藏后回调事件)   感觉很科学的样子
          this.transitioning = 0
          this.$element
            .removeClass('collapsing')
            .addClass('collapse')
            .trigger('hidden.bs.collapse')
        }
    
        if (!$.support.transition) return complete.call(this)
    
        this.$element
          [dimension](0)//style里面的height设置为0,触发过度效果
          .one('bsTransitionEnd', $.proxy(complete, this))
          .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
      }
    
      Collapse.prototype.toggle = function () {
        this[this.$element.hasClass('in') ? 'hide' : 'show']()//toggle做的很地道啊
      }
    
      Collapse.prototype.getParent = function () {
        return $(this.options.parent)
          .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')//获取子元素
          .each($.proxy(function (i, element) {//对子元素进行。。。。
            var $element = $(element)
            this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
          }, this))
          .end()
      }
    
      Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {//0:靶子元素,1:触发的元素(a)
        var isOpen = $element.hasClass('in')
    
        $element.attr('aria-expanded', isOpen)//expanded(扩大的,expand的过去式和过去分词)     记号
        $trigger
          .toggleClass('collapsed', !isOpen)
          .attr('aria-expanded', isOpen)
      }
    
      function getTargetFromTrigger($trigger) {//获取靶子元素
        var href
        var target = $trigger.attr('data-target')
          || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^s]+$)/, '') // strip for ie7       #号前面的东西替换成''.     
    
        return $(target)
      }
    
    
      // COLLAPSE PLUGIN DEFINITION
      // ==========================
    
      function Plugin(option) {
        return this.each(function () {
          var $this   = $(this)
          var data    = $this.data('bs.collapse')
          var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
    
          if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
          if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
          if (typeof option == 'string') data[option]()
        })
      }
    
      var old = $.fn.collapse
    
      $.fn.collapse             = Plugin
      $.fn.collapse.Constructor = Collapse
    
    
      // COLLAPSE NO CONFLICT
      // ====================
    
      $.fn.collapse.noConflict = function () {
        $.fn.collapse = old
        return this
      }
    
    
      // COLLAPSE DATA-API
      // =================
    
     $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
        var $this   = $(this)
    
        if (!$this.attr('data-target')) e.preventDefault()
    
        var $target = getTargetFromTrigger($this)//
        var data    = $target.data('bs.collapse')
        var option  = data ? 'toggle' : $this.data()
    
        Plugin.call($target, option)
      })
      /**$('[data-toggle="collapse"]').collapse('toggle');**/
    
    }(jQuery);
  • 相关阅读:
    关于android:screenOrientation="portrait"等
    《第一行代码》学习笔记44-位置服务(2)
    《第一行代码》学习笔记43-位置服务(1)
    《第一行代码》学习笔记42-网络(3)
    《第一行代码》学习笔记41-网络(2)
    spring JdbcTemplate如何返回多个结果集
    Python环境安装(Windows环境)
    C#使用 SharpSSH
    SqlDataReader生成动态Lambda表达式
    DataTable 转实体
  • 原文地址:https://www.cnblogs.com/xiaobie123/p/5997590.html
Copyright © 2011-2022 走看看