js/bootstrap-scrollspy.js
changeset 0 ba8ab09f730e
equal deleted inserted replaced
-1:000000000000 0:ba8ab09f730e
       
     1 /* =============================================================
       
     2  * bootstrap-scrollspy.js v2.3.1
       
     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 
       
    20 
       
    21 !function ($) {
       
    22 
       
    23   "use strict"; // jshint ;_;
       
    24 
       
    25 
       
    26  /* SCROLLSPY CLASS DEFINITION
       
    27   * ========================== */
       
    28 
       
    29   function ScrollSpy(element, options) {
       
    30     var process = $.proxy(this.process, this)
       
    31       , $element = $(element).is('body') ? $(window) : $(element)
       
    32       , href
       
    33     this.options = $.extend({}, $.fn.scrollspy.defaults, options)
       
    34     this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)
       
    35     this.selector = (this.options.target
       
    36       || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
       
    37       || '') + ' .nav li > a'
       
    38     this.$body = $('body')
       
    39     this.refresh()
       
    40     this.process()
       
    41   }
       
    42 
       
    43   ScrollSpy.prototype = {
       
    44 
       
    45       constructor: ScrollSpy
       
    46 
       
    47     , refresh: function () {
       
    48         var self = this
       
    49           , $targets
       
    50 
       
    51         this.offsets = $([])
       
    52         this.targets = $([])
       
    53 
       
    54         $targets = this.$body
       
    55           .find(this.selector)
       
    56           .map(function () {
       
    57             var $el = $(this)
       
    58               , href = $el.data('target') || $el.attr('href')
       
    59               , $href = /^#\w/.test(href) && $(href)
       
    60             return ( $href
       
    61               && $href.length
       
    62               && [[ $href.position().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]] ) || null
       
    63           })
       
    64           .sort(function (a, b) { return a[0] - b[0] })
       
    65           .each(function () {
       
    66             self.offsets.push(this[0])
       
    67             self.targets.push(this[1])
       
    68           })
       
    69       }
       
    70 
       
    71     , process: function () {
       
    72         var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
       
    73           , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
       
    74           , maxScroll = scrollHeight - this.$scrollElement.height()
       
    75           , offsets = this.offsets
       
    76           , targets = this.targets
       
    77           , activeTarget = this.activeTarget
       
    78           , i
       
    79 
       
    80         if (scrollTop >= maxScroll) {
       
    81           return activeTarget != (i = targets.last()[0])
       
    82             && this.activate ( i )
       
    83         }
       
    84 
       
    85         for (i = offsets.length; i--;) {
       
    86           activeTarget != targets[i]
       
    87             && scrollTop >= offsets[i]
       
    88             && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
       
    89             && this.activate( targets[i] )
       
    90         }
       
    91       }
       
    92 
       
    93     , activate: function (target) {
       
    94         var active
       
    95           , selector
       
    96 
       
    97         this.activeTarget = target
       
    98 
       
    99         $(this.selector)
       
   100           .parent('.active')
       
   101           .removeClass('active')
       
   102 
       
   103         selector = this.selector
       
   104           + '[data-target="' + target + '"],'
       
   105           + this.selector + '[href="' + target + '"]'
       
   106 
       
   107         active = $(selector)
       
   108           .parent('li')
       
   109           .addClass('active')
       
   110 
       
   111         if (active.parent('.dropdown-menu').length)  {
       
   112           active = active.closest('li.dropdown').addClass('active')
       
   113         }
       
   114 
       
   115         active.trigger('activate')
       
   116       }
       
   117 
       
   118   }
       
   119 
       
   120 
       
   121  /* SCROLLSPY PLUGIN DEFINITION
       
   122   * =========================== */
       
   123 
       
   124   var old = $.fn.scrollspy
       
   125 
       
   126   $.fn.scrollspy = function (option) {
       
   127     return this.each(function () {
       
   128       var $this = $(this)
       
   129         , data = $this.data('scrollspy')
       
   130         , options = typeof option == 'object' && option
       
   131       if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
       
   132       if (typeof option == 'string') data[option]()
       
   133     })
       
   134   }
       
   135 
       
   136   $.fn.scrollspy.Constructor = ScrollSpy
       
   137 
       
   138   $.fn.scrollspy.defaults = {
       
   139     offset: 10
       
   140   }
       
   141 
       
   142 
       
   143  /* SCROLLSPY NO CONFLICT
       
   144   * ===================== */
       
   145 
       
   146   $.fn.scrollspy.noConflict = function () {
       
   147     $.fn.scrollspy = old
       
   148     return this
       
   149   }
       
   150 
       
   151 
       
   152  /* SCROLLSPY DATA-API
       
   153   * ================== */
       
   154 
       
   155   $(window).on('load', function () {
       
   156     $('[data-spy="scroll"]').each(function () {
       
   157       var $spy = $(this)
       
   158       $spy.scrollspy($spy.data())
       
   159     })
       
   160   })
       
   161 
       
   162 }(window.jQuery);