assets/javascripts/bootstrap/scrollspy.js
changeset 114 af15590802a4
equal deleted inserted replaced
113:d4ec02c51c91 114:af15590802a4
       
     1 /* ========================================================================
       
     2  * Bootstrap: scrollspy.js v3.3.5
       
     3  * http://getbootstrap.com/javascript/#scrollspy
       
     4  * ========================================================================
       
     5  * Copyright 2011-2015 Twitter, Inc.
       
     6  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
       
     7  * ======================================================================== */
       
     8 
       
     9 
       
    10 +function ($) {
       
    11   'use strict';
       
    12 
       
    13   // SCROLLSPY CLASS DEFINITION
       
    14   // ==========================
       
    15 
       
    16   function ScrollSpy(element, options) {
       
    17     this.$body          = $(document.body)
       
    18     this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
       
    19     this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)
       
    20     this.selector       = (this.options.target || '') + ' .nav li > a'
       
    21     this.offsets        = []
       
    22     this.targets        = []
       
    23     this.activeTarget   = null
       
    24     this.scrollHeight   = 0
       
    25 
       
    26     this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
       
    27     this.refresh()
       
    28     this.process()
       
    29   }
       
    30 
       
    31   ScrollSpy.VERSION  = '3.3.5'
       
    32 
       
    33   ScrollSpy.DEFAULTS = {
       
    34     offset: 10
       
    35   }
       
    36 
       
    37   ScrollSpy.prototype.getScrollHeight = function () {
       
    38     return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
       
    39   }
       
    40 
       
    41   ScrollSpy.prototype.refresh = function () {
       
    42     var that          = this
       
    43     var offsetMethod  = 'offset'
       
    44     var offsetBase    = 0
       
    45 
       
    46     this.offsets      = []
       
    47     this.targets      = []
       
    48     this.scrollHeight = this.getScrollHeight()
       
    49 
       
    50     if (!$.isWindow(this.$scrollElement[0])) {
       
    51       offsetMethod = 'position'
       
    52       offsetBase   = this.$scrollElement.scrollTop()
       
    53     }
       
    54 
       
    55     this.$body
       
    56       .find(this.selector)
       
    57       .map(function () {
       
    58         var $el   = $(this)
       
    59         var href  = $el.data('target') || $el.attr('href')
       
    60         var $href = /^#./.test(href) && $(href)
       
    61 
       
    62         return ($href
       
    63           && $href.length
       
    64           && $href.is(':visible')
       
    65           && [[$href[offsetMethod]().top + offsetBase, href]]) || null
       
    66       })
       
    67       .sort(function (a, b) { return a[0] - b[0] })
       
    68       .each(function () {
       
    69         that.offsets.push(this[0])
       
    70         that.targets.push(this[1])
       
    71       })
       
    72   }
       
    73 
       
    74   ScrollSpy.prototype.process = function () {
       
    75     var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset
       
    76     var scrollHeight = this.getScrollHeight()
       
    77     var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()
       
    78     var offsets      = this.offsets
       
    79     var targets      = this.targets
       
    80     var activeTarget = this.activeTarget
       
    81     var i
       
    82 
       
    83     if (this.scrollHeight != scrollHeight) {
       
    84       this.refresh()
       
    85     }
       
    86 
       
    87     if (scrollTop >= maxScroll) {
       
    88       return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
       
    89     }
       
    90 
       
    91     if (activeTarget && scrollTop < offsets[0]) {
       
    92       this.activeTarget = null
       
    93       return this.clear()
       
    94     }
       
    95 
       
    96     for (i = offsets.length; i--;) {
       
    97       activeTarget != targets[i]
       
    98         && scrollTop >= offsets[i]
       
    99         && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
       
   100         && this.activate(targets[i])
       
   101     }
       
   102   }
       
   103 
       
   104   ScrollSpy.prototype.activate = function (target) {
       
   105     this.activeTarget = target
       
   106 
       
   107     this.clear()
       
   108 
       
   109     var selector = this.selector +
       
   110       '[data-target="' + target + '"],' +
       
   111       this.selector + '[href="' + target + '"]'
       
   112 
       
   113     var active = $(selector)
       
   114       .parents('li')
       
   115       .addClass('active')
       
   116 
       
   117     if (active.parent('.dropdown-menu').length) {
       
   118       active = active
       
   119         .closest('li.dropdown')
       
   120         .addClass('active')
       
   121     }
       
   122 
       
   123     active.trigger('activate.bs.scrollspy')
       
   124   }
       
   125 
       
   126   ScrollSpy.prototype.clear = function () {
       
   127     $(this.selector)
       
   128       .parentsUntil(this.options.target, '.active')
       
   129       .removeClass('active')
       
   130   }
       
   131 
       
   132 
       
   133   // SCROLLSPY PLUGIN DEFINITION
       
   134   // ===========================
       
   135 
       
   136   function Plugin(option) {
       
   137     return this.each(function () {
       
   138       var $this   = $(this)
       
   139       var data    = $this.data('bs.scrollspy')
       
   140       var options = typeof option == 'object' && option
       
   141 
       
   142       if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
       
   143       if (typeof option == 'string') data[option]()
       
   144     })
       
   145   }
       
   146 
       
   147   var old = $.fn.scrollspy
       
   148 
       
   149   $.fn.scrollspy             = Plugin
       
   150   $.fn.scrollspy.Constructor = ScrollSpy
       
   151 
       
   152 
       
   153   // SCROLLSPY NO CONFLICT
       
   154   // =====================
       
   155 
       
   156   $.fn.scrollspy.noConflict = function () {
       
   157     $.fn.scrollspy = old
       
   158     return this
       
   159   }
       
   160 
       
   161 
       
   162   // SCROLLSPY DATA-API
       
   163   // ==================
       
   164 
       
   165   $(window).on('load.bs.scrollspy.data-api', function () {
       
   166     $('[data-spy="scroll"]').each(function () {
       
   167       var $spy = $(this)
       
   168       Plugin.call($spy, $spy.data())
       
   169     })
       
   170   })
       
   171 
       
   172 }(jQuery);