In this repo i store all my websites, each in a different branch
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
5.8 KiB

  1. /**
  2. * Single Page Nav Plugin
  3. * Copyright (c) 2014 Chris Wojcik <hello@chriswojcik.net>
  4. * Dual licensed under MIT and GPL.
  5. * @author Chris Wojcik
  6. * @version 1.2.0
  7. */
  8. // Utility
  9. if (typeof Object.create !== 'function') {
  10. Object.create = function(obj) {
  11. function F() {}
  12. F.prototype = obj;
  13. return new F();
  14. };
  15. }
  16. (function($, window, document, undefined) {
  17. "use strict";
  18. var SinglePageNav = {
  19. init: function(options, container) {
  20. this.options = $.extend({}, $.fn.singlePageNav.defaults, options);
  21. this.container = container;
  22. this.$container = $(container);
  23. this.$links = this.$container.find('a');
  24. if (this.options.filter !== '') {
  25. this.$links = this.$links.filter(this.options.filter);
  26. }
  27. this.$window = $(window);
  28. this.$htmlbody = $('html, body');
  29. this.$links.on('click.singlePageNav', $.proxy(this.handleClick, this));
  30. this.didScroll = false;
  31. this.checkPosition();
  32. this.setTimer();
  33. },
  34. handleClick: function(e) {
  35. var self = this,
  36. link = e.currentTarget,
  37. $elem = $(link.hash);
  38. e.preventDefault();
  39. if ($elem.length) { // Make sure the target elem exists
  40. // Prevent active link from cycling during the scroll
  41. self.clearTimer();
  42. // Before scrolling starts
  43. if (typeof self.options.beforeStart === 'function') {
  44. self.options.beforeStart();
  45. }
  46. self.setActiveLink(link.hash);
  47. self.scrollTo($elem, function() {
  48. if (self.options.updateHash && history.pushState) {
  49. history.pushState(null,null, link.hash);
  50. }
  51. self.setTimer();
  52. // After scrolling ends
  53. if (typeof self.options.onComplete === 'function') {
  54. self.options.onComplete();
  55. }
  56. });
  57. }
  58. },
  59. scrollTo: function($elem, callback) {
  60. var self = this;
  61. var target = self.getCoords($elem).top;
  62. var called = false;
  63. self.$htmlbody.stop().animate(
  64. {scrollTop: target},
  65. {
  66. duration: self.options.speed,
  67. easing: self.options.easing,
  68. complete: function() {
  69. if (typeof callback === 'function' && !called) {
  70. callback();
  71. }
  72. called = true;
  73. }
  74. }
  75. );
  76. },
  77. setTimer: function() {
  78. var self = this;
  79. self.$window.on('scroll.singlePageNav', function() {
  80. self.didScroll = true;
  81. });
  82. self.timer = setInterval(function() {
  83. if (self.didScroll) {
  84. self.didScroll = false;
  85. self.checkPosition();
  86. }
  87. }, 250);
  88. },
  89. clearTimer: function() {
  90. clearInterval(this.timer);
  91. this.$window.off('scroll.singlePageNav');
  92. this.didScroll = false;
  93. },
  94. // Check the scroll position and set the active section
  95. checkPosition: function() {
  96. var scrollPos = this.$window.scrollTop();
  97. var currentSection = this.getCurrentSection(scrollPos);
  98. if(currentSection!==null) {
  99. this.setActiveLink(currentSection);
  100. }
  101. },
  102. getCoords: function($elem) {
  103. return {
  104. top: Math.round($elem.offset().top) - this.options.offset
  105. };
  106. },
  107. setActiveLink: function(href) {
  108. var $activeLink = this.$container.find("a[href$='" + href + "']");
  109. if (!$activeLink.hasClass(this.options.currentClass)) {
  110. this.$links.removeClass(this.options.currentClass);
  111. $activeLink.addClass(this.options.currentClass);
  112. }
  113. },
  114. getCurrentSection: function(scrollPos) {
  115. var i, hash, coords, section;
  116. for (i = 0; i < this.$links.length; i++) {
  117. hash = this.$links[i].hash;
  118. if ($(hash).length) {
  119. coords = this.getCoords($(hash));
  120. if (scrollPos >= coords.top - this.options.threshold) {
  121. section = hash;
  122. }
  123. }
  124. }
  125. // The current section or the first link if it is found
  126. return section || ((this.$links.length===0) ? (null) : (this.$links[0].hash));
  127. }
  128. };
  129. $.fn.singlePageNav = function(options) {
  130. return this.each(function() {
  131. var singlePageNav = Object.create(SinglePageNav);
  132. singlePageNav.init(options, this);
  133. });
  134. };
  135. $.fn.singlePageNav.defaults = {
  136. offset: 0,
  137. threshold: 120,
  138. speed: 400,
  139. currentClass: 'current',
  140. easing: 'swing',
  141. updateHash: false,
  142. filter: '',
  143. onComplete: false,
  144. beforeStart: false
  145. };
  146. })(jQuery, window, document);