diff options
| author | fat <[email protected]> | 2015-05-06 13:34:14 -0700 |
|---|---|---|
| committer | fat <[email protected]> | 2015-05-06 13:34:14 -0700 |
| commit | d1fbe200f46002431cdeebf965c4b789ef7ed267 (patch) | |
| tree | 43a7cc7667492e519b906f8a428935da2972ac14 /js/scrollspy.js | |
| parent | 09fb80568a52af6c440db971cdc6fd88eab8f8b5 (diff) | |
| download | bootstrap-d1fbe200f46002431cdeebf965c4b789ef7ed267.tar.xz bootstrap-d1fbe200f46002431cdeebf965c4b789ef7ed267.zip | |
remove closureness from plugins
Diffstat (limited to 'js/scrollspy.js')
| -rw-r--r-- | js/scrollspy.js | 424 |
1 files changed, 125 insertions, 299 deletions
diff --git a/js/scrollspy.js b/js/scrollspy.js index 150241b54..f860c1aba 100644 --- a/js/scrollspy.js +++ b/js/scrollspy.js @@ -1,346 +1,172 @@ -/** ======================================================================= - * Bootstrap: scrollspy.js v4.0.0 +/* ======================================================================== + * Bootstrap: scrollspy.js v3.3.4 * http://getbootstrap.com/javascript/#scrollspy * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== - * @fileoverview - Bootstrap's scrollspy plugin. - * - * Public Methods & Properties: - * - * + $.scrollspy - * + $.scrollspy.noConflict - * + $.scrollspy.Constructor - * + $.scrollspy.Constructor.VERSION - * + $.scrollspy.Constructor.Defaults - * + $.scrollspy.Constructor.Defaults.offset - * + $.scrollspy.Constructor.prototype.refresh - * - * ======================================================================== - */ - -'use strict'; - - -/** - * Our scrollspy class. - * @param {Element!} element - * @param {Object=} opt_config - * @constructor - */ -function ScrollSpy(element, opt_config) { - - /** @private {Element|Window} */ - this._scrollElement = element.tagName == 'BODY' ? window : element - - /** @private {Object} */ - this._config = $.extend({}, ScrollSpy['Defaults'], opt_config) - - /** @private {string} */ - this._selector = (this._config.target || '') + ' .nav li > a' - - /** @private {Array} */ - this._offsets = [] - - /** @private {Array} */ - this._targets = [] - - /** @private {Element} */ - this._activeTarget = null - - /** @private {number} */ - this._scrollHeight = 0 - - $(this._scrollElement).on('scroll.bs.scrollspy', this._process.bind(this)) - - this['refresh']() + * ======================================================================== */ - this._process() -} ++function ($) { + 'use strict'; -/** - * @const - * @type {string} - */ -ScrollSpy['VERSION'] = '4.0.0' + // SCROLLSPY CLASS DEFINITION + // ========================== + function ScrollSpy(element, options) { + this.$body = $(document.body) + this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) + this.options = $.extend({}, ScrollSpy.DEFAULTS, options) + this.selector = (this.options.target || '') + ' .nav li > a' + this.offsets = [] + this.targets = [] + this.activeTarget = null + this.scrollHeight = 0 -/** - * @const - * @type {Object} - */ -ScrollSpy['Defaults'] = { - 'offset': 10 -} - - -/** - * @const - * @type {string} - * @private - */ -ScrollSpy._NAME = 'scrollspy' - - -/** - * @const - * @type {string} - * @private - */ -ScrollSpy._DATA_KEY = 'bs.scrollspy' - - -/** - * @const - * @type {Function} - * @private - */ -ScrollSpy._JQUERY_NO_CONFLICT = $.fn[ScrollSpy._NAME] - - -/** - * @const - * @enum {string} - * @private - */ -ScrollSpy._Event = { - ACTIVATE: 'activate.bs.scrollspy' -} - - -/** - * @const - * @enum {string} - * @private - */ -ScrollSpy._ClassName = { - DROPDOWN_MENU : 'dropdown-menu', - ACTIVE : 'active' -} - - -/** - * @const - * @enum {string} - * @private - */ -ScrollSpy._Selector = { - DATA_SPY : '[data-spy="scroll"]', - ACTIVE : '.active', - LI_DROPDOWN : 'li.dropdown', - LI : 'li' -} - - -/** - * @param {Object=} opt_config - * @this {jQuery} - * @return {jQuery} - * @private - */ -ScrollSpy._jQueryInterface = function (opt_config) { - return this.each(function () { - var data = $(this).data(ScrollSpy._DATA_KEY) - var config = typeof opt_config === 'object' && opt_config || null - - if (!data) { - data = new ScrollSpy(this, config) - $(this).data(ScrollSpy._DATA_KEY, data) - } - - if (typeof opt_config === 'string') { - data[opt_config]() - } - }) -} - + this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) + this.refresh() + this.process() + } -/** - * Refresh the scrollspy target cache - */ -ScrollSpy.prototype['refresh'] = function () { - var offsetMethod = 'offset' - var offsetBase = 0 + ScrollSpy.VERSION = '3.3.4' - if (this._scrollElement !== this._scrollElement.window) { - offsetMethod = 'position' - offsetBase = this._getScrollTop() + ScrollSpy.DEFAULTS = { + offset: 10 } - this._offsets = [] - this._targets = [] - - this._scrollHeight = this._getScrollHeight() + ScrollSpy.prototype.getScrollHeight = function () { + return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) + } - var targets = /** @type {Array.<Element>} */ ($.makeArray($(this._selector))) + ScrollSpy.prototype.refresh = function () { + var that = this + var offsetMethod = 'offset' + var offsetBase = 0 - targets - .map(function (element, index) { - var target - var targetSelector = Bootstrap.getSelectorFromElement(element) + this.offsets = [] + this.targets = [] + this.scrollHeight = this.getScrollHeight() - if (targetSelector) { - target = $(targetSelector)[0] - } + if (!$.isWindow(this.$scrollElement[0])) { + offsetMethod = 'position' + offsetBase = this.$scrollElement.scrollTop() + } - if (target && (target.offsetWidth || target.offsetHeight)) { - // todo (fat): remove sketch reliance on jQuery position/offset - return [$(target)[offsetMethod]().top + offsetBase, targetSelector] - } - }) - .filter(function (item) { return item }) - .sort(function (a, b) { return a[0] - b[0] }) - .forEach(function (item, index) { - this._offsets.push(item[0]) - this._targets.push(item[1]) - }.bind(this)) -} - - -/** - * @private - */ -ScrollSpy.prototype._getScrollTop = function () { - return this._scrollElement === window ? - this._scrollElement.scrollY : this._scrollElement.scrollTop -} - - -/** - * @private - */ -ScrollSpy.prototype._getScrollHeight = function () { - return this._scrollElement.scrollHeight - || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight) -} - - -/** - * @private - */ -ScrollSpy.prototype._process = function () { - var scrollTop = this._getScrollTop() + this._config.offset - var scrollHeight = this._getScrollHeight() - var maxScroll = this._config.offset + scrollHeight - this._scrollElement.offsetHeight - - if (this._scrollHeight != scrollHeight) { - this['refresh']() + this.$body + .find(this.selector) + .map(function () { + var $el = $(this) + var href = $el.data('target') || $el.attr('href') + var $href = /^#./.test(href) && $(href) + + return ($href + && $href.length + && $href.is(':visible') + && [[$href[offsetMethod]().top + offsetBase, href]]) || null + }) + .sort(function (a, b) { return a[0] - b[0] }) + .each(function () { + that.offsets.push(this[0]) + that.targets.push(this[1]) + }) } - if (scrollTop >= maxScroll) { - var target = this._targets[this._targets.length - 1] - - if (this._activeTarget != target) { - this._activate(target) + ScrollSpy.prototype.process = function () { + var scrollTop = this.$scrollElement.scrollTop() + this.options.offset + var scrollHeight = this.getScrollHeight() + var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() + var offsets = this.offsets + var targets = this.targets + var activeTarget = this.activeTarget + var i + + if (this.scrollHeight != scrollHeight) { + this.refresh() } - } - if (this._activeTarget && scrollTop < this._offsets[0]) { - this._activeTarget = null - this._clear() - return - } + if (scrollTop >= maxScroll) { + return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) + } - for (var i = this._offsets.length; i--;) { - var isActiveTarget = this._activeTarget != this._targets[i] - && scrollTop >= this._offsets[i] - && (!this._offsets[i + 1] || scrollTop < this._offsets[i + 1]) + if (activeTarget && scrollTop < offsets[0]) { + this.activeTarget = null + return this.clear() + } - if (isActiveTarget) { - this._activate(this._targets[i]) + for (i = offsets.length; i--;) { + activeTarget != targets[i] + && scrollTop >= offsets[i] + && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) + && this.activate(targets[i]) } } -} - -/** - * @param {Element} target - * @private - */ -ScrollSpy.prototype._activate = function (target) { - this._activeTarget = target + ScrollSpy.prototype.activate = function (target) { + this.activeTarget = target - this._clear() + this.clear() - var selector = this._selector - + '[data-target="' + target + '"],' - + this._selector + '[href="' + target + '"]' + var selector = this.selector + + '[data-target="' + target + '"],' + + this.selector + '[href="' + target + '"]' - // todo (fat): this seems horribly wrong… getting all raw li elements up the tree ,_, - var parentListItems = $(selector).parents(ScrollSpy._Selector.LI) + var active = $(selector) + .parents('li') + .addClass('active') - for (var i = parentListItems.length; i--;) { - $(parentListItems[i]).addClass(ScrollSpy._ClassName.ACTIVE) + if (active.parent('.dropdown-menu').length) { + active = active + .closest('li.dropdown') + .addClass('active') + } - var itemParent = parentListItems[i].parentNode + active.trigger('activate.bs.scrollspy') + } - if (itemParent && $(itemParent).hasClass(ScrollSpy._ClassName.DROPDOWN_MENU)) { - var closestDropdown = $(itemParent).closest(ScrollSpy._Selector.LI_DROPDOWN)[0] - $(closestDropdown).addClass(ScrollSpy._ClassName.ACTIVE) - } + ScrollSpy.prototype.clear = function () { + $(this.selector) + .parentsUntil(this.options.target, '.active') + .removeClass('active') } - $(this._scrollElement).trigger(ScrollSpy._Event.ACTIVATE, { - relatedTarget: target - }) -} + // SCROLLSPY PLUGIN DEFINITION + // =========================== -/** - * @private - */ -ScrollSpy.prototype._clear = function () { - var activeParents = $(this._selector).parentsUntil(this._config.target, ScrollSpy._Selector.ACTIVE) + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.scrollspy') + var options = typeof option == 'object' && option - for (var i = activeParents.length; i--;) { - $(activeParents[i]).removeClass(ScrollSpy._ClassName.ACTIVE) + if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) + if (typeof option == 'string') data[option]() + }) } -} + var old = $.fn.scrollspy -/** - * ------------------------------------------------------------------------ - * jQuery Interface + noConflict implementaiton - * ------------------------------------------------------------------------ - */ + $.fn.scrollspy = Plugin + $.fn.scrollspy.Constructor = ScrollSpy -/** - * @const - * @type {Function} - */ -$.fn[ScrollSpy._NAME] = ScrollSpy._jQueryInterface + // SCROLLSPY NO CONFLICT + // ===================== -/** - * @const - * @type {Function} - */ -$.fn[ScrollSpy._NAME]['Constructor'] = ScrollSpy - - -/** - * @const - * @type {Function} - */ -$.fn[ScrollSpy._NAME]['noConflict'] = function () { - $.fn[ScrollSpy._NAME] = ScrollSpy._JQUERY_NO_CONFLICT - return this -} + $.fn.scrollspy.noConflict = function () { + $.fn.scrollspy = old + return this + } -/** - * ------------------------------------------------------------------------ - * Data Api implementation - * ------------------------------------------------------------------------ - */ + // SCROLLSPY DATA-API + // ================== -$(window).on('load.bs.scrollspy.data-api', function () { - var scrollSpys = /** @type {Array.<Element>} */ ($.makeArray($(ScrollSpy._Selector.DATA_SPY))) + $(window).on('load.bs.scrollspy.data-api', function () { + $('[data-spy="scroll"]').each(function () { + var $spy = $(this) + Plugin.call($spy, $spy.data()) + }) + }) - for (var i = scrollSpys.length; i--;) { - var $spy = $(scrollSpys[i]) - ScrollSpy._jQueryInterface.call($spy, /** @type {Object|null} */ ($spy.data())) - } -}) +}(jQuery); |
