File: //home/bristolfilton.co.uk/public_html/wp-content/themes/advance/js/unminified/headhesive.js
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define([], function () {
return factory();
});
} else if (typeof exports === 'object') {
module.exports = factory();
} else {
root.Headhesive = factory();
}
})(this, function () {
'use strict';
//= include helpers.js
/**
* Constructor
*/
var Headhesive = function (elem, options) {
// Return if feature test fails
if (! ('querySelector' in document && 'addEventListener' in window) ) {
return;
}
// Initial state
this.visible = false;
// Options
this.options = {
offset: 300,
offsetSide: 'top',
classes: {
clone: 'headhesive',
stick: 'headhesive--stick',
unstick: 'headhesive--unstick'
},
throttle: 250,
onInit: function () {},
onStick: function () {},
onUnstick: function () {},
onDestroy: function () {},
};
// Get elem, check if string, if not assume object passed in
this.elem = (typeof elem === 'string') ? document.querySelector(elem) : elem;
// Merge user options with default options
this.options = _mergeObj(this.options, options);
// Self init
this.init();
};
/**
* Headhesive prototype methods
*/
Headhesive.prototype = {
constructor: Headhesive,
/**
* Initialise Headhesive
*/
init: function () {
// Clone element
this.clonedElem = this.elem.cloneNode(true);
this.clonedElem.className += ' ' + this.options.classes.clone;
document.body.insertBefore(this.clonedElem, document.body.firstChild);
// Determin offset value
if (typeof this.options.offset === 'number') {
this.scrollOffset = this.options.offset;
} else if (typeof this.options.offset === 'string') {
this._setScrollOffset();
} else {
throw new Error('Invalid offset: ' + this.options.offset);
}
// Throttled events
this._throttleUpdate = _throttle(this.update.bind(this), this.options.throttle);
this._throttleScrollOffset = _throttle(this._setScrollOffset.bind(this), this.options.throttle);
// Events.
window.addEventListener('scroll', this._throttleUpdate, false);
window.addEventListener('resize', this._throttleScrollOffset, false);
// Callback.
this.options.onInit.call(this);
},
/**
* Sets the scrollOffset value.
*/
_setScrollOffset: function () {
if (typeof this.options.offset === 'string') {
this.scrollOffset = _getElemY(document.querySelector(this.options.offset), this.options.offsetSide);
}
},
/**
* Clean up DOM and remove events
*/
destroy: function () {
document.body.removeChild(this.clonedElem);
window.removeEventListener('scroll', this._throttleUpdate);
window.removeEventListener('resize', this._throttleScrollOffset);
// Callback.
this.options.onDestroy.call(this);
},
/**
* Logic for sticking element
*/
stick: function () {
if (!this.visible) {
this.clonedElem.className = this.clonedElem.className.replace(new RegExp('(^|\\s)*' + this.options.classes.unstick + '(\\s|$)*', 'g'), '');
this.clonedElem.className += ' ' + this.options.classes.stick;
this.visible = true;
// Callback.
this.options.onStick.call(this);
}
},
/**
* Logic for unsticking element
*/
unstick: function () {
if (this.visible) {
this.clonedElem.className = this.clonedElem.className.replace(new RegExp('(^|\\s)*' + this.options.classes.stick + '(\\s|$)*', 'g'), '');
this.clonedElem.className += ' ' + this.options.classes.unstick;
this.visible = false;
// Callback.
this.options.onUnstick.call(this);
}
},
/**
* Update status of elem
*/
update: function () {
if (_getScrollY() > this.scrollOffset) {
this.stick();
} else {
this.unstick();
}
},
};
return Headhesive;
});