(function($, window, document, undefined){
var OnePageNav=function(elem, options){
this.elem=elem;
this.$elem=$(elem);
this.options=options;
this.metadata=this.$elem.data('plugin-options');
this.$win=$(window);
this.sections={};
this.didScroll=false;
this.$doc=$(document);
this.docHeight=this.$doc.height();
};
OnePageNav.prototype={
defaults: {
navItems: 'a',
currentClass: 'current',
changeHash: false,
easing: 'swing',
filter: '',
scrollSpeed: 1500,
scrollThreshold: 0.5,
begin: false,
end: false,
scrollChange: false
},
init: function(){
this.config=$.extend({}, this.defaults, this.options, this.metadata);
this.$nav=this.$elem.find(this.config.navItems);
if(this.config.filter!==''){
this.$nav=this.$nav.filter(this.config.filter);
}
this.$nav.on('click.onePageNav', $.proxy(this.handleClick, this));
this.getPositions();
this.bindInterval();
this.$win.on('resize.onePageNav', $.proxy(this.getPositions, this));
return this;
},
adjustNav: function(self, $parent){
self.$elem.find('.' + self.config.currentClass).removeClass(self.config.currentClass);
$parent.addClass(self.config.currentClass);
},
bindInterval: function(){
var self=this;
var docHeight;
self.$win.on('scroll.onePageNav', function(){
self.didScroll=true;
});
self.t=setInterval(function(){
docHeight=self.$doc.height();
if(self.didScroll){
self.didScroll=false;
self.scrollChange();
}
if(docHeight!==self.docHeight){
self.docHeight=docHeight;
self.getPositions();
}}, 250);
},
getHash: function($link){
return $link.attr('href').split('#')[1];
},
getPositions: function(){
var self=this;
var linkHref;
var topPos;
var $target;
self.$nav.each(function(){
linkHref=self.getHash($(this));
$target=$('#' + linkHref);
if($target.length){
topPos=$target.offset().top;
self.sections[linkHref]=Math.round(topPos);
}});
},
getSection: function(windowPos){
var returnValue=null;
var windowHeight=Math.round(this.$win.height() * this.config.scrollThreshold);
for(var section in this.sections){
if((this.sections[section] - windowHeight) < windowPos){
returnValue=section;
}}
return returnValue;
},
handleClick: function(e){
var self=this;
var $link=$(e.currentTarget);
var $parent=$link.parent();
var newLoc='#' + self.getHash($link);
if(!$parent.hasClass(self.config.currentClass)){
if(self.config.begin){
self.config.begin();
}
self.adjustNav(self, $parent);
self.unbindInterval();
self.scrollTo(newLoc, function(){
if(self.config.changeHash){
window.location.hash=newLoc;
}
self.bindInterval();
if(self.config.end){
self.config.end();
}});
}
e.preventDefault();
},
scrollChange: function(){
var windowTop=this.$win.scrollTop();
var position=this.getSection(windowTop);
var $parent;
if(position!==null){
$parent=this.$elem.find('a[href$="#' + position + '"]').parent();
if(!$parent.hasClass(this.config.currentClass)){
this.adjustNav(this, $parent);
if(this.config.scrollChange){
this.config.scrollChange($parent);
}}
}},
scrollTo: function(target, callback){
var offset=$(target).offset().top-100;
$('html, body').animate({
scrollTop: offset
}, this.config.scrollSpeed, this.config.easing, callback);
},
unbindInterval: function(){
clearInterval(this.t);
this.$win.unbind('scroll.onePageNav');
}};
OnePageNav.defaults=OnePageNav.prototype.defaults;
$.fn.onePageNav=function(options){
return this.each(function(){
new OnePageNav(this, options).init();
});
};})(jQuery, window , document);