bootstrap-scrollspy.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /* =============================================================
  2. * bootstrap-scrollspy.js v2.0.2
  3. * http://twitter.github.com/bootstrap/javascript.html#scrollspy
  4. * =============================================================
  5. * Copyright 2012 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 ( $ ) {
  20. "use strict"
  21. /* SCROLLSPY CLASS DEFINITION
  22. * ========================== */
  23. function ScrollSpy( element, options) {
  24. var process = $.proxy(this.process, this)
  25. , $element = $(element).is('body') ? $(window) : $(element)
  26. , href
  27. this.options = $.extend({}, $.fn.scrollspy.defaults, options)
  28. this.$scrollElement = $element.on('scroll.scroll.data-api', process)
  29. this.selector = (this.options.target
  30. || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
  31. || '') + ' .nav li > a'
  32. this.$body = $('body').on('click.scroll.data-api', this.selector, process)
  33. this.refresh()
  34. this.process()
  35. }
  36. ScrollSpy.prototype = {
  37. constructor: ScrollSpy
  38. , refresh: function () {
  39. this.targets = this.$body
  40. .find(this.selector)
  41. .map(function () {
  42. var href = $(this).attr('href')
  43. return /^#\w/.test(href) && $(href).length ? href : null
  44. })
  45. this.offsets = $.map(this.targets, function (id) {
  46. return $(id).position().top
  47. })
  48. }
  49. , process: function () {
  50. var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
  51. , offsets = this.offsets
  52. , targets = this.targets
  53. , activeTarget = this.activeTarget
  54. , i
  55. for (i = offsets.length; i--;) {
  56. activeTarget != targets[i]
  57. && scrollTop >= offsets[i]
  58. && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
  59. && this.activate( targets[i] )
  60. }
  61. }
  62. , activate: function (target) {
  63. var active
  64. this.activeTarget = target
  65. this.$body
  66. .find(this.selector).parent('.active')
  67. .removeClass('active')
  68. active = this.$body
  69. .find(this.selector + '[href="' + target + '"]')
  70. .parent('li')
  71. .addClass('active')
  72. if ( active.parent('.dropdown-menu') ) {
  73. active.closest('li.dropdown').addClass('active')
  74. }
  75. }
  76. }
  77. /* SCROLLSPY PLUGIN DEFINITION
  78. * =========================== */
  79. $.fn.scrollspy = function ( option ) {
  80. return this.each(function () {
  81. var $this = $(this)
  82. , data = $this.data('scrollspy')
  83. , options = typeof option == 'object' && option
  84. if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
  85. if (typeof option == 'string') data[option]()
  86. })
  87. }
  88. $.fn.scrollspy.Constructor = ScrollSpy
  89. $.fn.scrollspy.defaults = {
  90. offset: 10
  91. }
  92. /* SCROLLSPY DATA-API
  93. * ================== */
  94. $(function () {
  95. $('[data-spy="scroll"]').each(function () {
  96. var $spy = $(this)
  97. $spy.scrollspy($spy.data())
  98. })
  99. })
  100. }( window.jQuery );