]>
Commit | Line | Data |
---|---|---|
5e1c08eb C |
1 | $(function() { |
2 | // $(document).foundation(); | |
3 | ||
4 | var $sidebar = $('#sidebar'); | |
5 | if ($sidebar.length) { | |
6 | var $docs = $('#docs'); | |
7 | var $nav = $sidebar.find('nav'); | |
8 | ||
9 | // | |
10 | // Setup sidebar navigation | |
11 | var traverse = new Traverse($nav, { | |
12 | threshold: 10, | |
13 | barOffset: $sidebar.position().top | |
14 | }); | |
15 | ||
16 | $nav.on('update.traverse', function(event, element) { | |
17 | $nav.find('section').removeClass('expand'); | |
18 | var $section = element.parents('section:first'); | |
19 | if ($section.length) { | |
20 | $section.addClass('expand'); | |
21 | } | |
22 | }); | |
23 | ||
24 | // | |
25 | // Bind the drawer layout | |
26 | var $drawerLayout = $('.drawer-layout'), | |
27 | $drawer = $drawerLayout.find('.drawer'), | |
28 | closeDrawer = function() { | |
29 | $drawer.removeClass('slide-right slide-left'); | |
30 | $drawer.find('.drawer-overlay').remove(); | |
31 | $drawerLayout.removeClass('drawer-open drawer-slide-left-large drawer-slide-right-large'); | |
32 | return false; | |
33 | }; | |
34 | ||
35 | // Drawer open buttons | |
36 | $drawerLayout.find('[data-drawer-slide]').click(function(e) { | |
37 | var $this = $(this), | |
38 | direction = $this.data('drawer-slide'); | |
39 | $drawerLayout.addClass('drawer-open'); | |
40 | $drawer.addClass('slide-' + direction); | |
41 | ||
42 | var $overlay = $('<a href="#" class="drawer-overlay"></a>') | |
43 | $drawer.append($overlay); | |
44 | $overlay.click(closeDrawer); | |
45 | ||
46 | return false; | |
47 | }); | |
48 | ||
49 | // Drawer close buttons | |
50 | $drawerLayout.find('[data-drawer-close]').click(closeDrawer); | |
51 | } | |
52 | }); | |
53 | ||
54 | /** | |
55 | * Creates a new instance of Traverse. | |
56 | * @class | |
57 | * @fires Traverse#init | |
58 | * @param {Object} element - jQuery object to add the trigger to. | |
59 | * @param {Object} options - Overrides to the default plugin settings. | |
60 | */ | |
61 | function Traverse(element, options) { | |
62 | this.$element = element; | |
63 | this.options = $.extend({}, Traverse.defaults, this.$element.data(), options); | |
64 | ||
65 | this._init(); | |
66 | } | |
67 | ||
68 | /** | |
69 | * Default settings for plugin | |
70 | */ | |
71 | Traverse.defaults = { | |
72 | /** | |
73 | * Amount of time, in ms, the animated scrolling should take between locations. | |
74 | * @option | |
75 | * @example 500 | |
76 | */ | |
77 | animationDuration: 500, | |
78 | /** | |
79 | * Animation style to use when scrolling between locations. | |
80 | * @option | |
81 | * @example 'ease-in-out' | |
82 | */ | |
83 | animationEasing: 'linear', | |
84 | /** | |
85 | * Number of pixels to use as a marker for location changes. | |
86 | * @option | |
87 | * @example 50 | |
88 | */ | |
89 | threshold: 50, | |
90 | /** | |
91 | * Class applied to the active locations link on the traverse container. | |
92 | * @option | |
93 | * @example 'active' | |
94 | */ | |
95 | activeClass: 'active', | |
96 | /** | |
97 | * Allows the script to manipulate the url of the current page, and if supported, alter the history. | |
98 | * @option | |
99 | * @example true | |
100 | */ | |
101 | deepLinking: false, | |
102 | /** | |
103 | * Number of pixels to offset the scroll of the page on item click if using a sticky nav bar. | |
104 | * @option | |
105 | * @example 25 | |
106 | */ | |
107 | barOffset: 0 | |
108 | }; | |
109 | ||
110 | /** | |
111 | * Initializes the Traverse plugin and calls functions to get equalizer functioning on load. | |
112 | * @private | |
113 | */ | |
114 | Traverse.prototype._init = function() { | |
115 | var id = this.$element[0].id, // || Foundation.GetYoDigits(6, 'traverse'), | |
116 | _this = this; | |
117 | this.$targets = $('[data-traverse-target]'); | |
118 | this.$links = this.$element.find('a'); | |
119 | this.$element.attr({ | |
120 | 'data-resize': id, | |
121 | 'data-scroll': id, | |
122 | 'id': id | |
123 | }); | |
124 | this.$active = $(); | |
125 | this.scrollPos = parseInt(window.pageYOffset, 10); | |
126 | ||
127 | this._events(); | |
128 | }; | |
129 | ||
130 | /** | |
131 | * Calculates an array of pixel values that are the demarcation lines between locations on the page. | |
132 | * Can be invoked if new elements are added or the size of a location changes. | |
133 | * @function | |
134 | */ | |
135 | Traverse.prototype.calcPoints = function(){ | |
136 | var _this = this, | |
137 | body = document.body, | |
138 | html = document.documentElement; | |
139 | ||
140 | this.points = []; | |
141 | this.winHeight = Math.round(Math.max(window.innerHeight, html.clientHeight)); | |
142 | this.docHeight = Math.round(Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight)); | |
143 | ||
144 | this.$targets.each(function(){ | |
145 | var $tar = $(this), | |
146 | pt = $tar.offset().top; // Math.round($tar.offset().top - _this.options.threshold); | |
147 | $tar.targetPoint = pt; | |
148 | _this.points.push(pt); | |
149 | }); | |
150 | }; | |
151 | ||
152 | /** | |
153 | * Initializes events for Traverse. | |
154 | * @private | |
155 | */ | |
156 | Traverse.prototype._events = function() { | |
157 | var _this = this, | |
158 | $body = $('html, body'), | |
159 | opts = { | |
160 | duration: _this.options.animationDuration, | |
161 | easing: _this.options.animationEasing | |
162 | }; | |
163 | ||
164 | $(window).one('load', function(){ | |
165 | _this.calcPoints(); | |
166 | _this._updateActive(); | |
167 | ||
168 | $(this).resize(function(e) { | |
169 | _this.reflow(); | |
170 | }).scroll(function(e) { | |
171 | _this._updateActive(); | |
172 | }); | |
173 | }) | |
174 | ||
175 | this.$element.on('click', 'a[href^="#"]', function(e) { //'click.zf.traverse' | |
176 | e.preventDefault(); | |
177 | var arrival = this.getAttribute('href').replace(".", "\\."), | |
178 | scrollPos = $(arrival).offset().top - _this.options.barOffset; // - _this.options.threshold / 2 - _this.options.barOffset; | |
179 | ||
180 | $body.stop(true).animate({ | |
181 | scrollTop: scrollPos | |
182 | }, opts); | |
183 | }); | |
184 | }; | |
185 | ||
186 | /** | |
187 | * Calls necessary functions to update Traverse upon DOM change | |
188 | * @function | |
189 | */ | |
190 | Traverse.prototype.reflow = function(){ | |
191 | this.calcPoints(); | |
192 | this._updateActive(); | |
193 | }; | |
194 | ||
195 | /** | |
196 | * Updates the visibility of an active location link, | |
197 | * and updates the url hash for the page, if deepLinking enabled. | |
198 | * @private | |
199 | * @function | |
200 | * @fires Traverse#update | |
201 | */ | |
202 | Traverse.prototype._updateActive = function(){ | |
203 | var winPos = parseInt(window.pageYOffset, 10), | |
204 | curIdx; | |
205 | ||
206 | if(winPos + this.winHeight === this.docHeight){ curIdx = this.points.length - 1; } | |
207 | else if(winPos < this.points[0]){ curIdx = 0; } | |
208 | else{ | |
209 | var isDown = this.scrollPos < winPos, | |
210 | _this = this, | |
211 | curVisible = this.points.filter(function(p, i){ | |
212 | return isDown ? | |
213 | p <= (winPos + _this.options.barOffset + _this.options.threshold) : | |
214 | (p - (_this.options.barOffset + _this.options.threshold)) <= winPos; | |
215 | // p <= (winPos - (offset - _this.options.threshold)) : | |
216 | // (p - (-offset + _this.options.threshold)) <= winPos; | |
217 | }); | |
218 | curIdx = curVisible.length ? curVisible.length - 1 : 0; | |
219 | } | |
220 | ||
221 | var $prev = this.$active; | |
222 | var $next = this.$links.eq(curIdx); | |
223 | this.$active.removeClass(this.options.activeClass); | |
224 | this.$active = $next.addClass(this.options.activeClass); | |
225 | ||
226 | if(this.options.deepLinking){ | |
227 | var hash = this.$active[0].getAttribute('href'); | |
228 | if(window.history.pushState){ | |
229 | window.history.pushState(null, null, hash); | |
230 | }else{ | |
231 | window.location.hash = hash; | |
232 | } | |
233 | } | |
234 | ||
235 | this.scrollPos = winPos; | |
236 | ||
237 | // Fire event if the active element was changed | |
238 | var changed = $prev[0] !== $next[0]; | |
239 | if (changed) { | |
240 | this.$element.trigger('update.traverse', [this.$active]); | |
241 | } | |
242 | }; |