scrollspy.js 4.24 KB
Newer Older
1
/* ========================================================================
2
 * Bootstrap: scrollspy.js v3.0.3
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
    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')
50
        var $href = /^#./.test(href) && $(href)
fat's avatar
fat committed
51
52
53

        return ($href
          && $href.length
54
          && $href.is(':visible')
fat's avatar
fat committed
55
          && [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null
fat's avatar
fat committed
56
57
58
59
60
61
62
      })
      .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
63

fat's avatar
fat committed
64
65
66
67
68
69
70
71
72
73
74
75
76
  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)
    }

77
    if (activeTarget && scrollTop <= offsets[0]) {
78
      return activeTarget != (i = targets[0]) && this.activate(i)
79
80
    }

fat's avatar
fat committed
81
82
83
84
85
86
    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
87
88
  }

fat's avatar
fat committed
89
90
91
92
  ScrollSpy.prototype.activate = function (target) {
    this.activeTarget = target

    $(this.selector)
fat's avatar
fat committed
93
      .parentsUntil(this.options.target, '.active')
fat's avatar
fat committed
94
95
      .removeClass('active')

Zlatan Vasović's avatar
Zlatan Vasović committed
96
97
98
    var selector = this.selector +
        '[data-target="' + target + '"],' +
        this.selector + '[href="' + target + '"]'
99

fat's avatar
fat committed
100
101
102
103
    var active = $(selector)
      .parents('li')
      .addClass('active')

Zlatan Vasović's avatar
Zlatan Vasović committed
104
    if (active.parent('.dropdown-menu').length) {
fat's avatar
fat committed
105
106
107
108
109
      active = active
        .closest('li.dropdown')
        .addClass('active')
    }

110
    active.trigger('activate.bs.scrollspy')
fat's avatar
fat committed
111
112
113
114
115
  }


  // SCROLLSPY PLUGIN DEFINITION
  // ===========================
116

117
118
  var old = $.fn.scrollspy

Jacob Thornton's avatar
Jacob Thornton committed
119
  $.fn.scrollspy = function (option) {
120
    return this.each(function () {
fat's avatar
fat committed
121
      var $this   = $(this)
122
      var data    = $this.data('bs.scrollspy')
fat's avatar
fat committed
123
124
      var options = typeof option == 'object' && option

125
      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
126
127
128
129
      if (typeof option == 'string') data[option]()
    })
  }

130
  $.fn.scrollspy.Constructor = ScrollSpy
131
132


fat's avatar
fat committed
133
134
  // SCROLLSPY NO CONFLICT
  // =====================
135
136
137
138
139
140
141

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


fat's avatar
fat committed
142
143
  // SCROLLSPY DATA-API
  // ==================
144

Jacob Thornton's avatar
Jacob Thornton committed
145
  $(window).on('load', function () {
146
147
148
149
    $('[data-spy="scroll"]').each(function () {
      var $spy = $(this)
      $spy.scrollspy($spy.data())
    })
150
  })
151

152
}(jQuery);