collapse.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /* ========================================================================
  2. * Bootstrap: collapse.js v3.3.7
  3. * http://getbootstrap.com/javascript/#collapse
  4. * ========================================================================
  5. * Copyright 2011-2016 Twitter, Inc.
  6. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  7. * ======================================================================== */
  8. /* jshint latedef: false */
  9. +function ($) {
  10. 'use strict';
  11. // COLLAPSE PUBLIC CLASS DEFINITION
  12. // ================================
  13. var Collapse = function (element, options) {
  14. this.$element = $(element)
  15. this.options = $.extend({}, Collapse.DEFAULTS, options)
  16. this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
  17. '[data-toggle="collapse"][data-target="#' + element.id + '"]')
  18. this.transitioning = null
  19. if (this.options.parent) {
  20. this.$parent = this.getParent()
  21. } else {
  22. this.addAriaAndCollapsedClass(this.$element, this.$trigger)
  23. }
  24. if (this.options.toggle) this.toggle()
  25. }
  26. Collapse.VERSION = '3.3.7'
  27. Collapse.TRANSITION_DURATION = 350
  28. Collapse.DEFAULTS = {
  29. toggle: true
  30. }
  31. Collapse.prototype.dimension = function () {
  32. var hasWidth = this.$element.hasClass('width')
  33. return hasWidth ? 'width' : 'height'
  34. }
  35. Collapse.prototype.show = function () {
  36. if (this.transitioning || this.$element.hasClass('in')) return
  37. var activesData
  38. var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
  39. if (actives && actives.length) {
  40. activesData = actives.data('bs.collapse')
  41. if (activesData && activesData.transitioning) return
  42. }
  43. var startEvent = $.Event('show.bs.collapse')
  44. this.$element.trigger(startEvent)
  45. if (startEvent.isDefaultPrevented()) return
  46. if (actives && actives.length) {
  47. Plugin.call(actives, 'hide')
  48. activesData || actives.data('bs.collapse', null)
  49. }
  50. var dimension = this.dimension()
  51. this.$element
  52. .removeClass('collapse')
  53. .addClass('collapsing')[dimension](0)
  54. .attr('aria-expanded', true)
  55. this.$trigger
  56. .removeClass('collapsed')
  57. .attr('aria-expanded', true)
  58. this.transitioning = 1
  59. var complete = function () {
  60. this.$element
  61. .removeClass('collapsing')
  62. .addClass('collapse in')[dimension]('')
  63. this.transitioning = 0
  64. this.$element
  65. .trigger('shown.bs.collapse')
  66. }
  67. if (!$.support.transition) return complete.call(this)
  68. var scrollSize = $.camelCase(['scroll', dimension].join('-'))
  69. this.$element
  70. .one('bsTransitionEnd', $.proxy(complete, this))
  71. .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
  72. }
  73. Collapse.prototype.hide = function () {
  74. if (this.transitioning || !this.$element.hasClass('in')) return
  75. var startEvent = $.Event('hide.bs.collapse')
  76. this.$element.trigger(startEvent)
  77. if (startEvent.isDefaultPrevented()) return
  78. var dimension = this.dimension()
  79. this.$element[dimension](this.$element[dimension]())[0].offsetHeight
  80. this.$element
  81. .addClass('collapsing')
  82. .removeClass('collapse in')
  83. .attr('aria-expanded', false)
  84. this.$trigger
  85. .addClass('collapsed')
  86. .attr('aria-expanded', false)
  87. this.transitioning = 1
  88. var complete = function () {
  89. this.transitioning = 0
  90. this.$element
  91. .removeClass('collapsing')
  92. .addClass('collapse')
  93. .trigger('hidden.bs.collapse')
  94. }
  95. if (!$.support.transition) return complete.call(this)
  96. this.$element
  97. [dimension](0)
  98. .one('bsTransitionEnd', $.proxy(complete, this))
  99. .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
  100. }
  101. Collapse.prototype.toggle = function () {
  102. this[this.$element.hasClass('in') ? 'hide' : 'show']()
  103. }
  104. Collapse.prototype.getParent = function () {
  105. return $(this.options.parent)
  106. .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
  107. .each($.proxy(function (i, element) {
  108. var $element = $(element)
  109. this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
  110. }, this))
  111. .end()
  112. }
  113. Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
  114. var isOpen = $element.hasClass('in')
  115. $element.attr('aria-expanded', isOpen)
  116. $trigger
  117. .toggleClass('collapsed', !isOpen)
  118. .attr('aria-expanded', isOpen)
  119. }
  120. function getTargetFromTrigger($trigger) {
  121. var href
  122. var target = $trigger.attr('data-target')
  123. || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
  124. return $(target)
  125. }
  126. // COLLAPSE PLUGIN DEFINITION
  127. // ==========================
  128. function Plugin(option) {
  129. return this.each(function () {
  130. var $this = $(this)
  131. var data = $this.data('bs.collapse')
  132. var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
  133. if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
  134. if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
  135. if (typeof option == 'string') data[option]()
  136. })
  137. }
  138. var old = $.fn.collapse
  139. $.fn.collapse = Plugin
  140. $.fn.collapse.Constructor = Collapse
  141. // COLLAPSE NO CONFLICT
  142. // ====================
  143. $.fn.collapse.noConflict = function () {
  144. $.fn.collapse = old
  145. return this
  146. }
  147. // COLLAPSE DATA-API
  148. // =================
  149. $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
  150. var $this = $(this)
  151. if (!$this.attr('data-target')) e.preventDefault()
  152. var $target = getTargetFromTrigger($this)
  153. var data = $target.data('bs.collapse')
  154. var option = data ? 'toggle' : $this.data()
  155. Plugin.call($target, option)
  156. })
  157. }(jQuery);