-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathjquery.navScroll.js
More file actions
155 lines (133 loc) · 5.14 KB
/
Copy pathjquery.navScroll.js
File metadata and controls
155 lines (133 loc) · 5.14 KB
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*!
* NavScroll.js
* Version: 1.4.1
* Author: Jeroen Hammann
*
* Copyright (c) 2014 Jeroen Hammann
* Released under the MIT license
*/
;(function ($, window, document, undefined) {
'use strict';
var pluginName = 'navScroll',
defaults = {
// The time it takes to scroll to the element (set this to 0 so it obviously won't show an animation).
scrollTime: 500,
// The class of the items which invokes the scroll animation. All anchor tags inside the element are clickable when the value is empty.
navItemClassName: '',
// Set the height of the navigation (to use as offset). 'auto' let's the plugin determine the height automatically, a number determines the height in px.
navHeight: 'auto',
// If your navigation hides and is used as a dropdown on small screens setting this to true hides the dropdown after a click.
mobileDropdown: false,
// Additionaly you can insert the mobile nav's classname here, when left empty the plugin searches for a <ul> in the same parent element.
mobileDropdownClassName: '',
// The window width, which functions as a breakpoint between desktop and mobile.
mobileBreakpoint: 1024,
// Set to 'true' if you want to enable scrollspy.
scrollSpy: false,
// Set to true if you want the parent of the anchor to have an active class instead of the anchor itself (only if ScrollSpy is enabled).
activeParent: false,
// Set the name of the active class. When left blank the class name will be 'active'.
activeClassName: 'active'
};
function NavScroll(element, options) {
this.element = element;
this.options = $.extend({
onScrollStart: function() {},
onScrollEnd: function() {}
}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}
NavScroll.prototype = {
init: function() {
var self, options, element, navItem, navOffset, scrollTime;
self = this;
options = self.options;
element = self.element;
if (options.navItemClassName === '') {
navItem = $(element).find('a');
} else {
navItem = $(element).find('.' + options.navItemClassName);
}
if (options.navHeight === 'auto') {
navOffset = $(element).height();
} else if (isNaN(options.navHeight)) {
throw new Error ('\'navHeight\' only accepts \'auto\' or a number as value.');
} else {
navOffset = options.navHeight;
}
navItem.on('click', function(e){
var url, parts, target, targetOffset, targetTop;
url = this.href;
parts = url.split('#');
target = parts[1];
if (target !== undefined) {
e.preventDefault();
targetOffset = $('#' + target).offset();
targetTop = targetOffset.top;
}
if ($(this).data('scrolltime') !== undefined) {
scrollTime = $(this).data('scrolltime');
} else {
scrollTime = options.scrollTime;
}
if (options.mobileDropdown && $(window).width() >= 0 && $(window).width() <= options.mobileBreakpoint) {
if (options.mobileDropdownClassName === '') {
$(element).find('ul').slideUp('fast');
} else {
$('.' + options.mobileDropdownClassName).slideUp('fast');
}
}
$('html, body').stop().animate({
scrollTop: targetTop - navOffset
}, scrollTime).promise().done(function() {
options.onScrollEnd.call(this);
});
options.onScrollStart.call(this);
});
if (options.scrollSpy) {
var scrollItems;
scrollItems = [];
navItem.each(function() {
var scrollItemId = $(this).attr('href');
if (scrollItemId.charAt(0) === '#') {
scrollItems.push($(scrollItemId));
}
});
$(window).on('scroll', function () {
self.scrollspy(options, navItem, scrollItems);
});
self.scrollspy(options, navItem, scrollItems);
}
},
scrollspy: function(options, navItem, scrollItems) {
var scrollPos, changeBounds, i, l;
scrollPos = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
changeBounds = window.innerHeight / 2 || document.documentElement.clientHeight / 2;
l = navItem.length;
for (i = 0; l > i; i++) {
var item = scrollItems[i];
if (item !== undefined) {
if (scrollPos > (item.offset().top - changeBounds)) {
if (options.activeParent) {
navItem.parent().removeClass(options.activeClassName);
$(navItem[i]).parent().addClass(options.activeClassName);
} else {
navItem.removeClass(options.activeClassName);
$(navItem[i]).addClass(options.activeClassName);
}
}
}
}
}
};
$.fn[pluginName] = function (options) {
return this.each(function () {
if (!$.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName,
new NavScroll(this, options));
}
});
};
})(jQuery, window, document);