1/* 2 * jQuery One Page Nav Plugin 3 * http://github.com/davist11/jQuery-One-Page-Nav 4 * 5 * Copyright (c) 2010 Trevor Davis (http://trevordavis.net) 6 * Dual licensed under the MIT and GPL licenses. 7 * Uses the same license as jQuery, see: 8 * http://jquery.org/license 9 * 10 * @version 3.0.0 11 * 12 * Example usage: 13 * $('#nav').onePageNav({ 14 * currentClass: 'current', 15 * changeHash: false, 16 * scrollSpeed: 750 17 * }); 18 */ 19 20;(function($, window, document, undefined){ 21 22 // our plugin constructor 23 var OnePageNav = function(elem, options){ 24 this.elem = elem; 25 this.$elem = $(elem); 26 this.options = options; 27 this.metadata = this.$elem.data('plugin-options'); 28 this.$win = $(window); 29 this.sections = {}; 30 this.didScroll = false; 31 this.$doc = $(document); 32 this.docHeight = this.$doc.height(); 33 }; 34 35 var firstItem = true; 36 37 // the plugin prototype 38 OnePageNav.prototype = { 39 defaults: { 40 navItems: 'a', 41 currentClass: 'current', 42 changeHash: false, 43 easing: 'swing', 44 filter: '', 45 scrollSpeed: 750, 46 scrollThreshold: 0.5, 47 begin: false, 48 end: false, 49 scrollChange: false 50 }, 51 52 init: function() { 53 // Introduce defaults that can be extended either 54 // globally or using an object literal. 55 this.config = $.extend({}, this.defaults, this.options, this.metadata); 56 57 this.$nav = this.$elem.find(this.config.navItems); 58 59 //Filter any links out of the nav 60 if(this.config.filter !== '') { 61 this.$nav = this.$nav.filter(this.config.filter); 62 } 63 64 //Handle clicks on the nav 65 this.$nav.on('click.onePageNav', $.proxy(this.handleClick, this)); 66 67 //Get the section positions 68 this.getPositions(); 69 70 //Handle scroll changes 71 this.bindInterval(); 72 73 //Update the positions on resize too 74 this.$win.on('resize.onePageNav', $.proxy(this.getPositions, this)); 75 76 return this; 77 }, 78 79 adjustNav: function(self, $parent) { 80 81 $('.site-nav li').removeClass(self.config.currentClass); 82 self.$elem.find('.' + self.config.currentClass).removeClass(self.config.currentClass); 83 84 $parent.addClass(self.config.currentClass); 85 var sectionLoc = $parent.find('a').attr('href'); 86 if( typeof sectionLoc !='undefined' && sectionLoc !='' ){ 87 88 var menuColor = $(sectionLoc).data('menucolor'); 89 if( menuColor =='' ){ 90 menuColor = $('article.homepage').data('menucolor'); 91 if( typeof menuColor =='undefined' || sectionLoc =='' ){ 92 menuColor = '#ffffff'; 93 } 94 } 95 96 97 $('ul.onetone-dots li a').css({'border':'2px solid '+menuColor}); 98 $('ul.onetone-dots li.'+self.config.currentClass+' a,ul.onetone-dots li.'+self.config.currentClass+' a:hover').css({'background-color':menuColor,'color':menuColor}); 99 100 } 101 102 }, 103 104 bindInterval: function() { 105 var self = this; 106 var docHeight; 107 108 self.$win.on('scroll.onePageNav', function() { 109 self.didScroll = true; 110 }); 111 112 self.t = setInterval(function() { 113 docHeight = self.$doc.height(); 114 115 //If it was scrolled 116 if(self.didScroll) { 117 self.didScroll = false; 118 self.scrollChange(); 119 } 120 121 //If the document height changes 122 if(docHeight !== self.docHeight) { 123 self.docHeight = docHeight; 124 self.getPositions(); 125 } 126 }, 250); 127 }, 128 129 getHash: function($link) { 130 return $link.attr('href').split('#')[1]; 131 }, 132 133 getPositions: function() { 134 var self = this; 135 var linkHref; 136 var topPos; 137 var $target; 138 139 self.$nav.each(function() { 140 linkHref = self.getHash($(this)); 141 $target = $('#' + linkHref); 142 143 if($target.length) { 144 topPos = $target.offset().top; 145 self.sections[linkHref] = Math.round(topPos); 146 } 147 }); 148 }, 149 150 getSection: function(windowPos) { 151 var returnValue = null; 152 var windowHeight = Math.round(this.$win.height() * this.config.scrollThreshold); 153 154 for(var section in this.sections) { 155 if((this.sections[section] - windowHeight) < windowPos) { 156 returnValue = section; 157 } 158 } 159 160 return returnValue; 161 }, 162 163 handleClick: function(e) { 164 var self = this; 165 var $link = $(e.currentTarget); 166 var $parent = $link.parent(); 167 var newLoc = '#' + self.getHash($link); 168 169 if( $("header").hasClass("fixed-header")){ 170 firstItem = false; 171 } 172 //// 173 var windowWidth = jQuery(window).width(); 174 if(windowWidth < 919) 175 $(".top-nav").toggle(); 176 177 if(!$parent.hasClass(self.config.currentClass)) { 178 //Start callback 179 if(self.config.begin) { 180 self.config.begin(); 181 } 182 183 //Change the highlighted nav item 184 185 $parent = $('a[href$="'+ newLoc + '"]').parent(); 186 self.adjustNav(self, $parent); 187 188 //Removing the auto-adjust on scroll 189 self.unbindInterval(); 190 191 //Scroll to the correct position 192 self.scrollTo(newLoc, function() { 193 //Do we need to change the hash? 194 if(self.config.changeHash) { 195 window.location.hash = newLoc; 196 } 197 198 //Add the auto-adjust on scroll back in 199 self.bindInterval(); 200 201 //End callback 202 if(self.config.end) { 203 self.config.end(); 204 } 205 }); 206 } 207 208 e.preventDefault(); 209 }, 210 211 scrollChange: function() { 212 var windowTop = this.$win.scrollTop();
213 var position = this.getSection(windowTop); 214 var $parent; 215 216 $('.main-nav li').removeClass(this.config.currentClass); 217 218 //If the position is set 219 if(position !== null) { 220 $parent = this.$elem.find('a[href$="#' + position + '"]').parent(); 221 222 //If it's not already the current section 223 if(!$parent.hasClass(this.config.currentClass)) { 224 //Change the highlighted nav item 225 $parent = $('a[href$="#' + position + '"]').parent(); 226 this.adjustNav(this, $parent); 227 228 //If there is a scrollChange callback 229 if(this.config.scrollChange) { 230 this.config.scrollChange($parent); 231 } 232 } 233 } 234 }, 235 236 scrollTo: function(target, callback) { 237 238 if( typeof $(target).offset() !== "undefined" ){ 239 var offset = $(target).offset().top; 240 241 //var id = $(target).attr('id'); 242 var selectorHeight = $('.sticky-header').height(); 243 //if(typeof $('section.'+ id).offset() !== 'undefined'){ 244 // var offset = $('section.'+ id).offset().top -selectorHeight; 245 var selectorHeight = $('.fxd-header').height(); 246 247 if( $("body.admin-bar").length ){ 248 if(jQuery(window).width() < 765) { 249 stickyTop = 46; 250 251 } else { 252 stickyTop = 32; 253 } 254 }else{ 255 stickyTop = 0; 256 } 257 258 selectorHeight = selectorHeight + stickyTop - 1; 259 260 261 if($(window).width() <= 919) { 262 $(".site-nav").hide(); 263 } 264 265 offset = offset - selectorHeight; 266 267 $('html, body').animate({ 268 scrollTop: offset 269 }, this.config.scrollSpeed, this.config.easing, callback); 270 271 //} 272 } 273 }, 274 275 unbindInterval: function() { 276 clearInterval(this.t); 277 this.$win.unbind('scroll.onePageNav'); 278 } 279 }; 280 281 OnePageNav.defaults = OnePageNav.prototype.defaults; 282 283 $.fn.onePageNav = function(options) { 284 return this.each(function() { 285 new OnePageNav(this, options).init(); 286 }); 287 }; 288 289})( jQuery, window , document );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.