Advertisement
Guest User

smoothscroll.js

a guest
Mar 26th, 2018
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (function ($) {
  2.  
  3.  
  4.     if (window.location.hash === '#page-top') {
  5.         changeUrlHash("", 5);
  6.     }
  7.  
  8.     var __toCheckOnScroll = {
  9.         items: {},
  10.         eachCategory: function (callback) {
  11.             for (var id in this.items) {
  12.  
  13.                 if (!this.items.hasOwnProperty(id)) {
  14.                     continue;
  15.                 }
  16.  
  17.                 callback(this.items[id]);
  18.             }
  19.         },
  20.         addItem: function (id, item) {
  21.             if (!this.items[id]) {
  22.                 this.items[id] = [];
  23.             }
  24.  
  25.             this.items[id].push(item);
  26.         },
  27.  
  28.         all: function () {
  29.             var result = [];
  30.  
  31.             for (var id in this.items) {
  32.  
  33.                 if (!this.items.hasOwnProperty(id)) {
  34.                     continue;
  35.                 }
  36.  
  37.                 result = result.concat(this.items[id]);
  38.             }
  39.  
  40.             return result;
  41.         }
  42.     };
  43.     var __alreadyScrolling = false;
  44.  
  45.  
  46.     function isAboveTheScreeMiddle(element) {
  47.         var breakPoint = window.innerHeight * 0.5;
  48.         var elPosition = {
  49.             top: $(element)[0].getBoundingClientRect().top,
  50.             bottom: $(element)[0].getBoundingClientRect().bottom
  51.         };
  52.  
  53.         if (elPosition.top >= 0 && elPosition.top < breakPoint) {
  54.             return true;
  55.         } else {
  56.             if (top < 0 && elPosition.bottom > 0) {
  57.                 return true;
  58.             }
  59.  
  60.         }
  61.  
  62.         return false;
  63.     }
  64.  
  65.  
  66.     function isInView(element, fullyInView) {
  67.         var pageTop = $(window).scrollTop();
  68.         var pageBottom = pageTop + $(window).height();
  69.         var elementTop = $(element).offset().top;
  70.         var elementBottom = elementTop + $(element).height();
  71.  
  72.         if (fullyInView === true) {
  73.             return ((pageTop < elementTop) && (pageBottom > elementBottom));
  74.         } else {
  75.             return ((elementTop <= pageBottom) && (elementBottom >= pageTop));
  76.         }
  77.     }
  78.  
  79.  
  80.     function getScrollToValue(elData) {
  81.         var offset = (!isNaN(parseFloat(elData.options.offset))) ? elData.options.offset : elData.options.offset.call(elData.target);
  82.         var scrollToValue = elData.target.offset().top - offset - $('body').offset().top;
  83.  
  84.         return scrollToValue;
  85.     }
  86.  
  87.  
  88.     function changeUrlHash(hash, timeout) {
  89.  
  90.         if (hash === location.hash.replace('#', '') || (hash === 'page-top' && '' === location.hash.replace('#', ''))) {
  91.             return;
  92.         }
  93.  
  94.         setTimeout(function () {
  95.             if (hash) {
  96.                 if (hash === 'page-top') {
  97.                     hash = " ";
  98.                 } else {
  99.                     hash = "#" + hash;
  100.                 }
  101.             } else {
  102.                 hash = " ";
  103.             }
  104.             if (history && history.replaceState) {
  105.                 history.replaceState({}, "", hash);
  106.             } else {
  107.             }
  108.         }, timeout || 100);
  109.         /* safari issue fixed by throtteling the event */
  110.     }
  111.  
  112.     function scrollItem(elData) {
  113.         if (__alreadyScrolling) {
  114.             return;
  115.         }
  116.  
  117.         __alreadyScrolling = true;
  118.         var scrollToValue = getScrollToValue(elData);
  119.  
  120.         $('html, body').animate({scrollTop: scrollToValue}, {
  121.                 easing: 'linear',
  122.                 complete: function () {
  123.                     // check for any updates
  124.                     var scrollToValue = getScrollToValue(elData);
  125.                     $('html, body').animate({scrollTop: scrollToValue}, {
  126.                             easing: 'linear',
  127.                             duration: 100,
  128.                             complete: function () {
  129.                                 __alreadyScrolling = false;
  130.                                 changeUrlHash(elData.id, 5);
  131.                             }
  132.                         }
  133.                     )
  134.                 }
  135.             }
  136.         );
  137.     }
  138.  
  139.     function getPageBaseUrl() {
  140.         return [location.protocol, '//', location.host, location.pathname].join('');
  141.     }
  142.  
  143.     function fallbackUrlParse(url) {
  144.         return url.split('?')[0].split('#')[0];
  145.     }
  146.  
  147.     function getABaseUrl(element) {
  148.         var href = jQuery(element)[0].href || "";
  149.         var url = "#";
  150.  
  151.         try {
  152.  
  153.             var _url = new window.URL(href);
  154.             url = [_url.protocol, '//', _url.host, _url.pathname].join('');
  155.  
  156.         } catch (e) {
  157.             url = fallbackUrlParse(href);
  158.         }
  159.  
  160.         return url;
  161.     }
  162.  
  163.     function getTargetForEl(element) {
  164.         var targetId = (element.attr('href') || "").split('#').pop(),
  165.             hrefBase = getABaseUrl(element),
  166.             target = null,
  167.             pageURL = getPageBaseUrl();
  168.  
  169.  
  170.         if (hrefBase.length && hrefBase !== pageURL) {
  171.             return target;
  172.         }
  173.  
  174.         if (targetId.trim().length) {
  175.             try {
  176.                 target = $('[id="' + targetId + '"]');
  177.             } catch (e) {
  178.                 console.log('error scrollSpy', e);
  179.             }
  180.         }
  181.  
  182.         if (target && target.length) {
  183.             return target;
  184.         }
  185.  
  186.         return null;
  187.     }
  188.  
  189.     $.fn.smoothScrollAnchor = function (options) {
  190.         var elements = $(this);
  191.  
  192.         options = jQuery.extend({
  193.             offset: 0
  194.         }, options);
  195.  
  196.         elements.each(function () {
  197.             var element = $(this);
  198.  
  199.             var target = options.target || getTargetForEl(element);
  200.             if (target && target.length) {
  201.  
  202.                 var elData = {
  203.                     element: element,
  204.                     options: options,
  205.                     target: target,
  206.                     targetSel: options.targetSel || '[id="' + target.attr('id').trim() + '"]',
  207.                     id: (target.attr('id') || '').trim()
  208.                 };
  209.  
  210.                 element.off('click').on('click', function (event) {
  211.                     event.preventDefault();
  212.                     event.stopPropagation();
  213.                     scrollItem(elData);
  214.                 });
  215.             }
  216.         });
  217.     };
  218.  
  219.     $.fn.scrollSpy = function (options) {
  220.         var elements = $(this);
  221.         var id = 'spy-' + parseInt(Date.now() * Math.random());
  222.  
  223.         elements.each(function () {
  224.             var element = $(this);
  225.             options = jQuery.extend({
  226.                 onChange: function () {
  227.                 },
  228.                 onLeave: function () {
  229.                 },
  230.                 smoothScrollAnchor: false,
  231.                 offset: 0
  232.             }, options);
  233.  
  234.             if (element.is('a') && (element.attr('href') || "").indexOf('#') !== -1) {
  235.  
  236.                 var target = getTargetForEl(element);
  237.  
  238.                 if (target) {
  239.                     var elData = {
  240.                         element: element,
  241.                         options: options,
  242.                         target: target,
  243.                         targetSel: '[id="' + target.attr('id').trim() + '"]',
  244.                         id: target.attr('id').trim()
  245.  
  246.                     };
  247.                     __toCheckOnScroll.addItem(id, elData);
  248.                     element.data('scrollSpy', elData);
  249.  
  250.                     if (options.smoothScrollAnchor) {
  251.                         element.smoothScrollAnchor({
  252.                             offset: options.offset
  253.                         });
  254.                     }
  255.                 }
  256.             }
  257.         })
  258.     };
  259.  
  260.  
  261.     function update() {
  262.         __toCheckOnScroll.eachCategory(function (items) {
  263.             var ordered = items.sort(function (itemA, itemB) {
  264.                 return itemA.target.offset().top - itemB.target.offset().top;
  265.             });
  266.             var lastItem = ordered.filter(function (item) {
  267.                 return item.target.offset().top <= window.scrollY + window.innerHeight * 0.25;
  268.             }).pop();
  269.  
  270.             ordered.forEach((function (item) {
  271.                 if (lastItem && item.element.is(lastItem.element)) {
  272.                     changeUrlHash(item.id, 5);
  273.                     item.options.onChange.call(item.element);
  274.                 } else {
  275.                     item.options.onLeave.call(item.element);
  276.                 }
  277.             }));
  278.         });
  279.     }
  280.  
  281.     $(window).scroll(update);
  282.  
  283.     $(window).bind('smoothscroll.update', update);
  284.  
  285.     $(function () {
  286.         var hash = window.location.hash.replace('#', '');
  287.         var currentItem = __toCheckOnScroll.all().filter(function (item) {
  288.             return item.targetSel === '[id="' + hash.trim() + '"]';
  289.         });
  290.  
  291.  
  292.         $(window).on('load', function () {
  293.             if (currentItem.length) {
  294.                 scrollItem(currentItem[0]);
  295.             }
  296.             update();
  297.         });
  298.     });
  299.  
  300. })(jQuery);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement