JAVASCRIPT   55

headhesive

Guest on 2nd July 2022 01:32:44 AM

  1. /*!
  2.  * headhesive v1.1.1 - An on-demand sticky header
  3.  * Copyright (c) Mark Goodyear — @markgdyr — markgoodyear.com
  4.  * License: MIT
  5.  */
  6.  */
  7. (function(window, document, undefined) {
  8.   "use strict";
  9.   var _mergeObj = function(to, from) {
  10.     for (var p in from) {
  11.       if (from.hasOwnProperty(p)) {
  12.         to[p] = typeof from[p] === "object" ? _mergeObj(to[p], from[p]) : from[p];
  13.       }
  14.     }
  15.     return to;
  16.   };
  17.   var _throttle = function(func, wait) {
  18.     var _now = Date.now || function() {
  19.       return new Date().getTime();
  20.     };
  21.     var context, args, result;
  22.     var timeout = null;
  23.     var previous = 0;
  24.     var later = function() {
  25.       previous = _now();
  26.       timeout = null;
  27.       result = func.apply(context, args);
  28.       context = args = null;
  29.     };
  30.     return function() {
  31.       var now = _now();
  32.       var remaining = wait - (now - previous);
  33.       context = this;
  34.       args = arguments;
  35.       if (remaining <= 0) {
  36.         clearTimeout(timeout);
  37.         timeout = null;
  38.         previous = now;
  39.         result = func.apply(context, args);
  40.         context = args = null;
  41.       } else if (!timeout) {
  42.         timeout = setTimeout(later, remaining);
  43.       }
  44.       return result;
  45.     };
  46.   };
  47.   var _getScrollY = function() {
  48.     return window.pageYOffset !== undefined ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
  49.   };
  50.   function _getElemY(elem) {
  51.     var top = 0;
  52.     while (elem) {
  53.       top += elem.offsetTop;
  54.       elem = elem.offsetParent;
  55.     }
  56.     return top;
  57.   }
  58.   var Headhesive = function(elem, options) {
  59.     if (!("querySelector" in document && "addEventListener" in window)) {
  60.       return;
  61.     }
  62.     this.visible = false;
  63.     this.options = {
  64.       offset: 300,
  65.       classes: {
  66.         clone: "headhesive",
  67.         stick: "headhesive--stick",
  68.         unstick: "headhesive--unstick"
  69.       },
  70.       throttle: 250,
  71.       onInit: function() {},
  72.       onStick: function() {},
  73.       onUnstick: function() {},
  74.       onDestroy: function() {}
  75.     };
  76.     this.elem = typeof elem === "string" ? document.querySelector(elem) : elem;
  77.     this.options = _mergeObj(this.options, options);
  78.     this.init();
  79.   };
  80.   Headhesive.prototype = {
  81.     constructor: Headhesive,
  82.     init: function() {
  83.       this.clonedElem = this.elem.cloneNode(true);
  84.       this.clonedElem.className += " " + this.options.classes.clone;
  85.       document.body.insertBefore(this.clonedElem, document.body.firstChild);
  86.       if (typeof this.options.offset === "number") {
  87.         this.scrollOffset = this.options.offset;
  88.       } else if (typeof this.options.offset === "string") {
  89.         this.scrollOffset = _getElemY(document.querySelector(this.options.offset));
  90.       } else {
  91.         throw new Error("Invalid offset: " + this.options.offset);
  92.       }
  93.       this._throttleUpdate = _throttle(this.update.bind(this), this.options.throttle);
  94.       window.addEventListener("scroll", this._throttleUpdate, false);
  95.       this.options.onInit.call(this);
  96.     },
  97.     destroy: function() {
  98.       document.body.removeChild(this.clonedElem);
  99.       window.removeEventListener("scroll", this._throttleUpdate);
  100.       this.options.onDestroy.call(this);
  101.     },
  102.     stick: function() {
  103.       if (!this.visible) {
  104.         this.clonedElem.className = this.clonedElem.className.replace(new RegExp("(^|\\s)*" + this.options.classes.unstick + "(\\s|$)*", "g"", "");
  105.         this.clonedElem.className += " " + this.options.classes.stick;
  106.         this.visible = true;
  107.         this.options.onStick.call(this);
  108.       }
  109.     },
  110.     unstick: function() {
  111.       if (this.visible) {
  112.         this.clonedElem.className = this.clonedElem.className.replace(new RegExp("(^|\\s)*" + this.options.classes.stick + "(\\s|$)*", "g"", "");
  113.         this.clonedElem.className += " " + this.options.classes.unstick;
  114.         this.visible = false;
  115.         this.options.onUnstick.call(this);
  116.       }
  117.     },
  118.     update: function() {
  119.       if (_getScrollY() > this.scrollOffset) {
  120.         this.stick();
  121.       } else {
  122.         this.unstick();
  123.       }
  124.     }
  125.   };
  126.   window.Headhesive = Headhesive;
  127. })(window, docume

Raw Paste


Login or Register to edit or fork this paste. It's free.