scrollspy.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /* ========================================================================
  2. * Bootstrap: scrollspy.js v3.1.1
  3. * http://getbootstrap.com/javascript/#scrollspy
  4. * ========================================================================
  5. * Copyright 2011-2014 Twitter, Inc.
  6. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  7. * ======================================================================== */
  8. +function ($) {
  9. 'use strict';
  10. // SCROLLSPY CLASS DEFINITION
  11. // ==========================
  12. function ScrollSpy(element, options) {
  13. var href
  14. var process = $.proxy(this.process, this)
  15. this.$element = $(element).is('body') ? $(window) : $(element)
  16. this.$body = $('body')
  17. this.$scrollElement = this.$element.on('scroll.bs.scroll-spy.data-api', process)
  18. this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
  19. this.selector = (this.options.target
  20. || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
  21. || '') + ' .nav li > a'
  22. this.offsets = $([])
  23. this.targets = $([])
  24. this.activeTarget = null
  25. this.refresh()
  26. this.process()
  27. }
  28. ScrollSpy.DEFAULTS = {
  29. offset: 10
  30. }
  31. ScrollSpy.prototype.refresh = function () {
  32. var offsetMethod = this.$element[0] == window ? 'offset' : 'position'
  33. this.offsets = $([])
  34. this.targets = $([])
  35. var self = this
  36. var $targets = this.$body
  37. .find(this.selector)
  38. .map(function () {
  39. var $el = $(this)
  40. var href = $el.data('target') || $el.attr('href')
  41. var $href = /^#./.test(href) && $(href)
  42. return ($href
  43. && $href.length
  44. && $href.is(':visible')
  45. && [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null
  46. })
  47. .sort(function (a, b) { return a[0] - b[0] })
  48. .each(function () {
  49. self.offsets.push(this[0])
  50. self.targets.push(this[1])
  51. })
  52. }
  53. ScrollSpy.prototype.process = function () {
  54. var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
  55. var scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
  56. var maxScroll = scrollHeight - this.$scrollElement.height()
  57. var offsets = this.offsets
  58. var targets = this.targets
  59. var activeTarget = this.activeTarget
  60. var i
  61. if (scrollTop >= maxScroll) {
  62. return activeTarget != (i = targets.last()[0]) && this.activate(i)
  63. }
  64. if (activeTarget && scrollTop <= offsets[0]) {
  65. return activeTarget != (i = targets[0]) && this.activate(i)
  66. }
  67. for (i = offsets.length; i--;) {
  68. activeTarget != targets[i]
  69. && scrollTop >= offsets[i]
  70. && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
  71. && this.activate( targets[i] )
  72. }
  73. }
  74. ScrollSpy.prototype.activate = function (target) {
  75. this.activeTarget = target
  76. $(this.selector)
  77. .parentsUntil(this.options.target, '.active')
  78. .removeClass('active')
  79. var selector = this.selector +
  80. '[data-target="' + target + '"],' +
  81. this.selector + '[href="' + target + '"]'
  82. var active = $(selector)
  83. .parents('li')
  84. .addClass('active')
  85. if (active.parent('.dropdown-menu').length) {
  86. active = active
  87. .closest('li.dropdown')
  88. .addClass('active')
  89. }
  90. active.trigger('activate.bs.scrollspy')
  91. }
  92. // SCROLLSPY PLUGIN DEFINITION
  93. // ===========================
  94. var old = $.fn.scrollspy
  95. $.fn.scrollspy = function (option) {
  96. return this.each(function () {
  97. var $this = $(this)
  98. var data = $this.data('bs.scrollspy')
  99. var options = typeof option == 'object' && option
  100. if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
  101. if (typeof option == 'string') data[option]()
  102. })
  103. }
  104. $.fn.scrollspy.Constructor = ScrollSpy
  105. // SCROLLSPY NO CONFLICT
  106. // =====================
  107. $.fn.scrollspy.noConflict = function () {
  108. $.fn.scrollspy = old
  109. return this
  110. }
  111. // SCROLLSPY DATA-API
  112. // ==================
  113. $(window).on('load', function () {
  114. $('[data-spy="scroll"]').each(function () {
  115. var $spy = $(this)
  116. $spy.scrollspy($spy.data())
  117. })
  118. })
  119. }(jQuery);