scrollspy.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /* ========================================================================
  2. * Bootstrap: scrollspy.js v3.0.3
  3. * http://getbootstrap.com/javascript/#scrollspy
  4. * ========================================================================
  5. * Copyright 2013 Twitter, Inc.
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. * ======================================================================== */
  19. +function ($) { "use strict";
  20. // SCROLLSPY CLASS DEFINITION
  21. // ==========================
  22. function ScrollSpy(element, options) {
  23. var href
  24. var process = $.proxy(this.process, this)
  25. this.$element = $(element).is('body') ? $(window) : $(element)
  26. this.$body = $('body')
  27. this.$scrollElement = this.$element.on('scroll.bs.scroll-spy.data-api', process)
  28. this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
  29. this.selector = (this.options.target
  30. || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
  31. || '') + ' .nav li > a'
  32. this.offsets = $([])
  33. this.targets = $([])
  34. this.activeTarget = null
  35. this.refresh()
  36. this.process()
  37. }
  38. ScrollSpy.DEFAULTS = {
  39. offset: 10
  40. }
  41. ScrollSpy.prototype.refresh = function () {
  42. var offsetMethod = this.$element[0] == window ? 'offset' : 'position'
  43. this.offsets = $([])
  44. this.targets = $([])
  45. var self = this
  46. var $targets = this.$body
  47. .find(this.selector)
  48. .map(function () {
  49. var $el = $(this)
  50. var href = $el.data('target') || $el.attr('href')
  51. var $href = /^#\w/.test(href) && $(href)
  52. return ($href
  53. && $href.length
  54. && [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null
  55. })
  56. .sort(function (a, b) { return a[0] - b[0] })
  57. .each(function () {
  58. self.offsets.push(this[0])
  59. self.targets.push(this[1])
  60. })
  61. }
  62. ScrollSpy.prototype.process = function () {
  63. var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
  64. var scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
  65. var maxScroll = scrollHeight - this.$scrollElement.height()
  66. var offsets = this.offsets
  67. var targets = this.targets
  68. var activeTarget = this.activeTarget
  69. var i
  70. if (scrollTop >= maxScroll) {
  71. return activeTarget != (i = targets.last()[0]) && this.activate(i)
  72. }
  73. for (i = offsets.length; i--;) {
  74. activeTarget != targets[i]
  75. && scrollTop >= offsets[i]
  76. && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
  77. && this.activate( targets[i] )
  78. }
  79. }
  80. ScrollSpy.prototype.activate = function (target) {
  81. this.activeTarget = target
  82. $(this.selector)
  83. .parents('.active')
  84. .removeClass('active')
  85. var selector = this.selector
  86. + '[data-target="' + target + '"],'
  87. + this.selector + '[href="' + target + '"]'
  88. var active = $(selector)
  89. .parents('li')
  90. .addClass('active')
  91. if (active.parent('.dropdown-menu').length) {
  92. active = active
  93. .closest('li.dropdown')
  94. .addClass('active')
  95. }
  96. active.trigger('activate.bs.scrollspy')
  97. }
  98. // SCROLLSPY PLUGIN DEFINITION
  99. // ===========================
  100. var old = $.fn.scrollspy
  101. $.fn.scrollspy = function (option) {
  102. return this.each(function () {
  103. var $this = $(this)
  104. var data = $this.data('bs.scrollspy')
  105. var options = typeof option == 'object' && option
  106. if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
  107. if (typeof option == 'string') data[option]()
  108. })
  109. }
  110. $.fn.scrollspy.Constructor = ScrollSpy
  111. // SCROLLSPY NO CONFLICT
  112. // =====================
  113. $.fn.scrollspy.noConflict = function () {
  114. $.fn.scrollspy = old
  115. return this
  116. }
  117. // SCROLLSPY DATA-API
  118. // ==================
  119. $(window).on('load', function () {
  120. $('[data-spy="scroll"]').each(function () {
  121. var $spy = $(this)
  122. $spy.scrollspy($spy.data())
  123. })
  124. })
  125. }(jQuery);