-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscrollspy.js
117 lines (117 loc) · 4.43 KB
/
scrollspy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
(function($) {
var Plugin, ScrollSpy, old;
ScrollSpy = function(element, options) {
var process;
process = $.proxy(this.process, this);
this.$body = $("body");
this.$scrollElement = ($(element).is("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;
this.$scrollElement.on("scroll.bs.scrollspy", process);
this.refresh();
this.process();
};
Plugin = function(option) {
return this.each(function() {
var $this, data, options;
$this = $(this);
data = $this.data("bs.scrollspy");
options = typeof option === "object" && option;
if (!data) {
$this.data("bs.scrollspy", (data = new ScrollSpy(this, options)));
}
if (typeof option === "string") {
data[option]();
}
});
};
"use strict";
ScrollSpy.VERSION = "3.3.0";
ScrollSpy.DEFAULTS = {
offset: 10
};
ScrollSpy.prototype.getScrollHeight = function() {
return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight);
};
ScrollSpy.prototype.refresh = function() {
var offsetBase, offsetMethod, self;
offsetMethod = "offset";
offsetBase = 0;
if (!$.isWindow(this.$scrollElement[0])) {
offsetMethod = "position";
offsetBase = this.$scrollElement.scrollTop();
}
this.offsets = [];
this.targets = [];
this.scrollHeight = this.getScrollHeight();
self = this;
this.$body.find(this.selector).map(function() {
var $el, $href, href;
$el = $(this);
href = $el.data("target") || $el.attr("href");
$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() {
self.offsets.push(this[0]);
self.targets.push(this[1]);
});
};
ScrollSpy.prototype.process = function() {
var activeTarget, i, maxScroll, offsets, scrollHeight, scrollTop, targets;
scrollTop = this.$scrollElement.scrollTop() + this.options.offset;
scrollHeight = this.getScrollHeight();
maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height();
offsets = this.offsets;
targets = this.targets;
activeTarget = this.activeTarget;
i = void 0;
if (this.scrollHeight !== scrollHeight) {
this.refresh();
}
if (scrollTop >= maxScroll) {
return activeTarget !== (i = targets[targets.length - 1]) && this.activate(i);
}
if (activeTarget && scrollTop < offsets[0]) {
this.activeTarget = null;
return this.clear();
}
i = offsets.length;
while (i--) {
activeTarget !== targets[i] && scrollTop >= offsets[i] && (!offsets[i + 1] || scrollTop <= offsets[i + 1]) && this.activate(targets[i]);
}
};
ScrollSpy.prototype.activate = function(target) {
var active, selector;
this.activeTarget = target;
this.clear();
selector = this.selector + "[data-target=\"" + target + "\"]," + this.selector + "[href=\"" + target + "\"]";
active = $(selector).parents("li").addClass("active");
if (active.parent(".dropdown-menu").length) {
active = active.closest("li.dropdown").addClass("active");
}
active.trigger("activate.bs.scrollspy");
};
ScrollSpy.prototype.clear = function() {
$(this.selector).parentsUntil(this.options.target, ".active").removeClass("active");
};
old = $.fn.scrollspy;
$.fn.scrollspy = Plugin;
$.fn.scrollspy.Constructor = ScrollSpy;
$.fn.scrollspy.noConflict = function() {
$.fn.scrollspy = old;
return this;
};
$(window).on("load.bs.scrollspy.data-api", function() {
$("[data-spy=\"scroll\"]").each(function() {
var $spy;
$spy = $(this);
Plugin.call($spy, $spy.data());
});
});
})(jQuery);