scrollspy.js 4.06 KB
Newer Older
1
/* ========================================================================
Mark Otto's avatar
Mark Otto committed
2
 * Bootstrap: scrollspy.js v3.1.0
3
 * http://getbootstrap.com/javascript/#scrollspy
4
 * ========================================================================
Zlatan Vasović's avatar
Zlatan Vasović committed
5
 * Copyright 2013 Twitter, Inc.
6
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7
 * ======================================================================== */
Jacob Thornton's avatar
Jacob Thornton committed
8

9

XhmikosR's avatar
XhmikosR committed
10
+function ($) { 'use strict';
11

fat's avatar
fat committed
12
13
  // SCROLLSPY CLASS DEFINITION
  // ==========================
14

Jacob Thornton's avatar
Jacob Thornton committed
15
  function ScrollSpy(element, options) {
fat's avatar
fat committed
16
17
18
    var href
    var process  = $.proxy(this.process, this)

fat's avatar
fat committed
19
    this.$element       = $(element).is('body') ? $(window) : $(element)
fat's avatar
fat committed
20
    this.$body          = $('body')
fat's avatar
fat committed
21
    this.$scrollElement = this.$element.on('scroll.bs.scroll-spy.data-api', process)
fat's avatar
fat committed
22
23
    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)
    this.selector       = (this.options.target
Jacob Thornton's avatar
Jacob Thornton committed
24
      || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
25
      || '') + ' .nav li > a'
fat's avatar
fat committed
26
27
28
29
    this.offsets        = $([])
    this.targets        = $([])
    this.activeTarget   = null

30
    this.refresh()
31
    this.process()
Jacob Thornton's avatar
Jacob Thornton committed
32
33
  }

fat's avatar
fat committed
34
35
36
37
38
  ScrollSpy.DEFAULTS = {
    offset: 10
  }

  ScrollSpy.prototype.refresh = function () {
fat's avatar
fat committed
39
40
    var offsetMethod = this.$element[0] == window ? 'offset' : 'position'

fat's avatar
fat committed
41
42
43
44
45
46
47
48
49
50
51
52
53
    this.offsets = $([])
    this.targets = $([])

    var self     = this
    var $targets = this.$body
      .find(this.selector)
      .map(function () {
        var $el   = $(this)
        var href  = $el.data('target') || $el.attr('href')
        var $href = /^#\w/.test(href) && $(href)

        return ($href
          && $href.length
fat's avatar
fat committed
54
          && [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null
fat's avatar
fat committed
55
56
57
58
59
60
61
      })
      .sort(function (a, b) { return a[0] - b[0] })
      .each(function () {
        self.offsets.push(this[0])
        self.targets.push(this[1])
      })
  }
Jacob Thornton's avatar
Jacob Thornton committed
62

fat's avatar
fat committed
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
  ScrollSpy.prototype.process = function () {
    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset
    var scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
    var maxScroll    = scrollHeight - this.$scrollElement.height()
    var offsets      = this.offsets
    var targets      = this.targets
    var activeTarget = this.activeTarget
    var i

    if (scrollTop >= maxScroll) {
      return activeTarget != (i = targets.last()[0]) && this.activate(i)
    }

    for (i = offsets.length; i--;) {
      activeTarget != targets[i]
        && scrollTop >= offsets[i]
        && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
        && this.activate( targets[i] )
    }
Jacob Thornton's avatar
Jacob Thornton committed
82
83
  }

fat's avatar
fat committed
84
85
86
87
88
89
90
91
92
93
  ScrollSpy.prototype.activate = function (target) {
    this.activeTarget = target

    $(this.selector)
      .parents('.active')
      .removeClass('active')

    var selector = this.selector
      + '[data-target="' + target + '"],'
      + this.selector + '[href="' + target + '"]'
94

fat's avatar
fat committed
95
96
97
98
99
100
101
102
103
104
    var active = $(selector)
      .parents('li')
      .addClass('active')

    if (active.parent('.dropdown-menu').length)  {
      active = active
        .closest('li.dropdown')
        .addClass('active')
    }

105
    active.trigger('activate.bs.scrollspy')
fat's avatar
fat committed
106
107
108
109
110
  }


  // SCROLLSPY PLUGIN DEFINITION
  // ===========================
111

112
113
  var old = $.fn.scrollspy

Jacob Thornton's avatar
Jacob Thornton committed
114
  $.fn.scrollspy = function (option) {
115
    return this.each(function () {
fat's avatar
fat committed
116
      var $this   = $(this)
117
      var data    = $this.data('bs.scrollspy')
fat's avatar
fat committed
118
119
      var options = typeof option == 'object' && option

120
      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
121
122
123
124
      if (typeof option == 'string') data[option]()
    })
  }

125
  $.fn.scrollspy.Constructor = ScrollSpy
126
127


fat's avatar
fat committed
128
129
  // SCROLLSPY NO CONFLICT
  // =====================
130
131
132
133
134
135
136

  $.fn.scrollspy.noConflict = function () {
    $.fn.scrollspy = old
    return this
  }


fat's avatar
fat committed
137
138
  // SCROLLSPY DATA-API
  // ==================
139

Jacob Thornton's avatar
Jacob Thornton committed
140
  $(window).on('load', function () {
141
142
143
144
    $('[data-spy="scroll"]').each(function () {
      var $spy = $(this)
      $spy.scrollspy($spy.data())
    })
145
  })
146

147
}(jQuery);