audero-sticky
Advanced tools
Comparing version 0.2.0 to 0.3.0
{ | ||
"name": "audero-sticky", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "Audero Sticky is a polyfill for the CSS position: sticky with no dependencies and support for multiple module systems.", | ||
@@ -5,0 +5,0 @@ "main": "src/audero-sticky.js", |
@@ -1,3 +0,3 @@ | ||
/*! audero-sticky.js 0.2.0 | Aurelio De Rosa (@AurelioDeRosa) | MIT/GPL-3.0 Licensed */ | ||
!function(a,b){"use strict";"function"==typeof define&&define.amd?define(b):"object"==typeof module&&module.exports?module.exports=b():a.Sticky=b()}(this,function(){"use strict";function a(a,b,c){var d=document.createEvent("Event");d.initEvent(b,!0,!0);for(var e in c)c.hasOwnProperty(e)&&(d[e]=c[e]);a.dispatchEvent(d)}function b(a){var b={};a=a||{};for(var c in q)q.hasOwnProperty(c)&&(b[c]=a[c]||q[c]);return b}function c(a,b){var c=new RegExp("\\b"+b+"\\b");c.test(a.className)||(a.className+=" "+b)}function d(a,b){var c=new RegExp("\\b"+b+"\\b");a.className=a.className.replace(c,"").trim()}function e(a){var b,e;return c(a.element,a.settings.activeClass),b=window.getComputedStyle(a.element),e={marginBottom:b.marginBottom,marginTop:b.marginTop},d(a.element,a.settings.activeClass),e}function f(a,b){b.forEach(function(b){a[b]=""})}function g(a,b,c){c||(c=Object.keys(b)),c.forEach(function(c){a[c]=b[c]})}function h(a,b){var c=[].slice.call(document.querySelectorAll(b));return c.indexOf(a)+1}function i(a){var b={};for(var c in a)b[c]=a[c]+"px";return b}function j(a){f(a.element.style,r.concat(["marginTop","marginBottom"])),a.element.style.position=a._position,a._placeholder&&a._placeholder.parentNode&&a._placeholder.parentNode.removeChild(a._placeholder)}function k(a,b){var c={},d=window.getComputedStyle(a),e=a.parentNode.getBoundingClientRect();return"auto"!==d.top?(c.start=a.getBoundingClientRect().top-parseFloat(d.top),c.end=e.bottom-~~parseFloat(b.marginBottom)):(c.start=a.getBoundingClientRect().bottom+parseFloat(d.bottom),c.end=e.top+~~parseFloat(b.marginTop)),c.start+=window.pageYOffset,c.end+=window.pageYOffset,c}function l(a){var b=a.element.getBoundingClientRect();g(a._placeholder.style,window.getComputedStyle(a.element),["top","bottom","marginTop","marginBottom","marginLeft","marginRight"]),g(a._placeholder.style,i(b),["width","height","left"])}function m(b){function f(){l(b),b._position=b.element.style.position,g(b.element.style,{position:"fixed"}),g(b.element.style,b._placeholder.style,r),b.element.parentNode.insertBefore(b._placeholder,b.element),n=!0,a(b.element,"stickystart"),c(b.element,b.settings.activeClass)}function h(){j(b),n=!1,a(b.element,"stickyend"),d(b.element,b.settings.activeClass)}function i(){p=n?k(b._placeholder,o):k(b.element,o);var a=~~parseFloat(window.getComputedStyle(b.element).height),c=p.end-a-window.pageYOffset,d=window.pageYOffset>=p.start&&window.pageYOffset<=p.end;d?(n||f(),b.element.style.top=c-s>=0?"":c+"px"):n&&h()}function m(){p=n?k(b._placeholder,o):k(b.element,o);var a=~~parseFloat(window.getComputedStyle(b.element).height),c=window.pageYOffset+window.innerHeight,d=p.end+a-c,e=c<=p.start&&c>=p.end;e?(n||f(),b.element.style.bottom=0>=d+s?"":-d+"px"):n&&h()}var n=!1,o=e(b),p=k(b.element,o),q=window.getComputedStyle(b.element),s="auto"!==q.top?parseFloat(q.top):parseFloat(q.bottom);return"auto"!==q.top?i:m}function n(a){return function(){window.removeEventListener("resize",a._handlers.resize),a.destroy(),a.init(),a._handlers.scroll()}}function o(a){window.addEventListener("load",a._handlers.scroll),window.addEventListener("scroll",a._handlers.scroll),window.addEventListener("resize",a._handlers.resize)}function p(a,c){this.element=a,this.settings=b(c),this._placeholder=null,this._position="",this._handlers={}}var q={selector:".sticky",activeClass:"sticky--active"},r=["width","height","left","marginLeft","marginRight","zIndex"];return p.isFeatureSupported=function(){var a=document.createElement("div");return a.style.cssText="position:sticky",!!a.style.position},p.autoInit=function(a){a=a||q,[].forEach.call(document.querySelectorAll(a.selector),function(b){var c=new p(b,a);c.init()})},p.prototype.init=function(){var a=this.element.getBoundingClientRect();this._placeholder=document.createElement("div"),this._handlers.scroll=m(this),this._handlers.resize=n(this),this._placeholder.style.zIndex=h(this.element,this.settings.selector),g(this._placeholder.style,window.getComputedStyle(this.element),["top","bottom","marginTop","marginBottom","marginLeft","marginRight"]),g(this._placeholder.style,i(a),["width","height","left"]),o(this)},p.prototype.destroy=function(){j(this),window.removeEventListener("scroll",this._handlers.scroll),window.removeEventListener("resize",this._handlers.resize),this._handlers={},this._position="",this._placeholder=null},p}); | ||
/*! audero-sticky.js 0.3.0 | Aurelio De Rosa (@AurelioDeRosa) | MIT/GPL-3.0 Licensed */ | ||
!function(a,b){"use strict";"function"==typeof define&&define.amd?define(b):"object"==typeof module&&module.exports?module.exports=b():a.Sticky=b()}(this,function(){"use strict";function a(a,b){return a[w]&&b?a[w][b]:a[w]}function b(a,b,c){if(a[w]||(a[w]={}),"string"==typeof b)return void(a[w][b]=c);for(var d in b)b.hasOwnProperty(d)&&(a[w][d]=b[d])}function c(a){delete a[w]}function d(a,b,c){var d=document.createEvent("Event");d.initEvent(b,!0,!0);for(var e in c)c.hasOwnProperty(e)&&(d[e]=c[e]);a.dispatchEvent(d)}function e(a){var b={};a=a||{};for(var c in u)u.hasOwnProperty(c)&&(b[c]=a[c]||u[c]);return b}function f(a,b){var c=new RegExp("\\b"+b+"\\b");c.test(a.className)||(a.className+=" "+b)}function g(a,b){var c=new RegExp("\\b"+b+"\\b");a.className=a.className.replace(c,"").trim()}function h(a){var b,c;return f(a.element,a.settings.activeClass),b=window.getComputedStyle(a.element),c={marginBottom:b.marginBottom,marginTop:b.marginTop},g(a.element,a.settings.activeClass),c}function i(a,b){b.forEach(function(b){a[b]=""})}function j(a,b,c){c||(c=Object.keys(b)),c.forEach(function(c){a[c]=b[c]})}function k(a,b){var c=[].slice.call(document.querySelectorAll(b));return c.indexOf(a)+1}function l(a){var b={};for(var c in a)b[c]=a[c]+"px";return b}function m(b){var c=a(b.element);i(b.element.style,v.concat(["marginTop","marginBottom"])),b.element.style.position=c.position,c.placeholder&&c.placeholder.parentNode&&c.placeholder.parentNode.removeChild(c.placeholder)}function n(a,b){var c={},d=window.getComputedStyle(a),e=a.parentNode.getBoundingClientRect();return"auto"!==d.top?(c.start=a.getBoundingClientRect().top-parseFloat(d.top),c.end=e.bottom-(parseFloat(b.marginBottom)||0)):(c.start=a.getBoundingClientRect().bottom+parseFloat(d.bottom),c.end=e.top+(parseFloat(b.marginTop)||0)),c.start+=window.pageYOffset,c.end+=window.pageYOffset,c}function o(b){var c=b.element.getBoundingClientRect(),d=a(b.element,"placeholder");j(d.style,window.getComputedStyle(b.element),["top","bottom","marginTop","marginBottom","marginLeft","marginRight"]),j(d.style,l(c),["width","height","left"])}function p(c){function e(){o(c),b(c.element,"position",c.element.style.position),j(c.element.style,{position:"fixed"}),j(c.element.style,s.placeholder.style,v),c.element.parentNode.insertBefore(s.placeholder,c.element),d(c.element,"stickystart"),f(c.element,c.settings.activeClass)}function i(){m(c),d(c.element,"stickyend"),g(c.element,c.settings.activeClass)}function k(){var a=s.placeholder.parentNode;q=a?n(s.placeholder,p):n(c.element,p);var b=parseFloat(window.getComputedStyle(c.element).height)||0,d=q.end-b-window.pageYOffset,f=window.pageYOffset>=q.start&&window.pageYOffset<=q.end;f?(a||e(),c.element.style.top=d-t>=0?"":d+"px"):a&&i()}function l(){var a=s.placeholder.parentNode;q=a?n(s.placeholder,p):n(c.element,p);var b=parseFloat(window.getComputedStyle(c.element).height)||0,d=window.pageYOffset+window.innerHeight,f=q.end+b-d,g=d<=q.start&&d>=q.end;g?(a||e(),c.element.style.bottom=0>=f+t?"":-f+"px"):a&&i()}var p=h(c),q=n(c.element,p),r=window.getComputedStyle(c.element),s=a(c.element),t="auto"!==r.top?parseFloat(r.top):parseFloat(r.bottom);return"auto"!==r.top?k:l}function q(b){return function(){b.destroy(),b.init(),a(b.element,"handlers").scroll()}}function r(b){var c=a(b.element,"handlers");window.addEventListener("load",c.scroll),window.addEventListener("scroll",c.scroll),window.addEventListener("resize",c.resize)}function s(b){var c=a(b.element,"handlers");window.removeEventListener("load",c.scroll),window.removeEventListener("scroll",c.scroll),window.removeEventListener("resize",c.resize)}function t(a,b){this.element=a,this.settings=e(b)}var u={selector:".sticky",activeClass:"sticky--active"},v=["width","height","left","marginLeft","marginRight","zIndex"],w="auderoSticky";return t.isFeatureSupported=function(){var a=["ms","webkit"],b="position:sticky;",c=document.createElement("div");return a.forEach(function(a){b+="position:-"+a+"-sticky;"}),c.style.cssText=b,!!c.style.position},t.autoInit=function(a){var b=a&&a.selector?a.selector:u.selector;[].forEach.call(document.querySelectorAll(b),function(b){var c=new t(b,a);c.init()})},t.prototype.init=function(){if(a(this.element))throw new Error("This element has already been initialized");var c=document.createElement(this.element.nodeName);b(this.element,"placeholder",c),b(this.element,"handlers",{scroll:p(this),resize:q(this)}),j(c.style,{visibility:"hidden",zIndex:k(this.element,this.settings.selector)}),o(this),r(this)},t.prototype.destroy=function(){m(this),s(this),c(this.element)},t}); | ||
//# sourceMappingURL=audero-sticky.min.js.map |
{ | ||
"name": "audero-sticky", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "Audero Sticky is a polyfill for the CSS position: sticky with no dependencies and support for multiple module systems.", | ||
@@ -5,0 +5,0 @@ "main": "src/audero-sticky.js", |
# Audero Sticky | ||
[![Code Climate](https://codeclimate.com/github/AurelioDeRosa/audero-sticky/badges/gpa.svg)](https://codeclimate.com/github/AurelioDeRosa/audero-sticky) | ||
[Audero Sticky](https://github.com/AurelioDeRosa/audero-sticky) is a polyfill for the CSS `position: sticky` with no | ||
@@ -4,0 +6,0 @@ dependencies and support for multiple module systems. |
@@ -49,2 +49,62 @@ (function(root, factory) { | ||
/** | ||
* The namespace used to store data related to the library | ||
* on the elements of a page | ||
* | ||
* @type {string} | ||
*/ | ||
var namespace = 'auderoSticky'; | ||
/** | ||
* Gets the value of the required property for a given element. | ||
* If <code>property</code> is not provided, an object containing all | ||
* the data set is returned. | ||
* | ||
* @param {HTMLElement} element The element whose value is returned | ||
* @param {string} [property] The name of the property whose value is returned | ||
* | ||
* @returns {*} | ||
*/ | ||
function getData(element, property) { | ||
return element[namespace] && property ? element[namespace][property] : element[namespace]; | ||
} | ||
/** | ||
* Sets the value of the required property for a given element. | ||
* If <code>property</code> is an object, all its key-value pairs are set. | ||
* | ||
* @param {HTMLElement} element The element whose value is set | ||
* @param {(string|Object)} property The name of the property whose value is set. | ||
* If an object is provided, all of its key-value pairs are set. | ||
* @param {*} [value] The value to set | ||
*/ | ||
function setData(element, property, value) { | ||
if (!element[namespace]) { | ||
element[namespace] = {}; | ||
} | ||
if (typeof property === 'string') { | ||
element[namespace][property] = value; | ||
return; | ||
} | ||
for(var key in property) { | ||
if (!property.hasOwnProperty(key)) { | ||
continue; | ||
} | ||
element[namespace][key] = property[key]; | ||
} | ||
} | ||
/** | ||
* Removes all the data from a given element | ||
* | ||
* @param {HTMLElement} element The element whose data are removed | ||
*/ | ||
function removeData(element) { | ||
delete element[namespace]; | ||
} | ||
/** | ||
* Triggers an event on an element | ||
@@ -215,2 +275,4 @@ * | ||
function cleanUp(sticky) { | ||
var data = getData(sticky.element); | ||
resetStyleProperties( | ||
@@ -223,6 +285,6 @@ sticky.element.style, | ||
); | ||
sticky.element.style.position = sticky._position; | ||
sticky.element.style.position = data.position; | ||
if (sticky._placeholder && sticky._placeholder.parentNode) { | ||
sticky._placeholder.parentNode.removeChild(sticky._placeholder); | ||
if (data.placeholder && data.placeholder.parentNode) { | ||
data.placeholder.parentNode.removeChild(data.placeholder); | ||
} | ||
@@ -250,6 +312,6 @@ } | ||
boundaries.start = element.getBoundingClientRect().top - parseFloat(elementStyle.top); | ||
boundaries.end = parentStyle.bottom - ~~parseFloat(stickyMargins.marginBottom); | ||
boundaries.end = parentStyle.bottom - (parseFloat(stickyMargins.marginBottom) || 0); | ||
} else { | ||
boundaries.start = element.getBoundingClientRect().bottom + parseFloat(elementStyle.bottom); | ||
boundaries.end = parentStyle.top + ~~parseFloat(stickyMargins.marginTop); | ||
boundaries.end = parentStyle.top + (parseFloat(stickyMargins.marginTop) || 0); | ||
} | ||
@@ -274,5 +336,6 @@ | ||
var startPosition = sticky.element.getBoundingClientRect(); | ||
var placeholder = getData(sticky.element, 'placeholder'); | ||
copyStyleProperties( | ||
sticky._placeholder.style, | ||
placeholder.style, | ||
window.getComputedStyle(sticky.element), | ||
@@ -289,3 +352,3 @@ [ | ||
copyStyleProperties( | ||
sticky._placeholder.style, | ||
placeholder.style, | ||
convertNumbersToPixels(startPosition), | ||
@@ -309,6 +372,6 @@ [ | ||
function onScroll(sticky) { | ||
var isAdded = false; | ||
var stickyMargins = getStickyMargins(sticky); | ||
var boundaries = calculateBoundaries(sticky.element, stickyMargins); | ||
var elementStyle = window.getComputedStyle(sticky.element); | ||
var data = getData(sticky.element); | ||
var distanceFromSide = elementStyle.top !== 'auto' ? | ||
@@ -320,3 +383,3 @@ parseFloat(elementStyle.top) : | ||
updatePlaceholderStyle(sticky); | ||
sticky._position = sticky.element.style.position; | ||
setData(sticky.element, 'position', sticky.element.style.position); | ||
copyStyleProperties( | ||
@@ -328,5 +391,4 @@ sticky.element.style, | ||
); | ||
copyStyleProperties(sticky.element.style, sticky._placeholder.style, properties); | ||
sticky.element.parentNode.insertBefore(sticky._placeholder, sticky.element); | ||
isAdded = true; | ||
copyStyleProperties(sticky.element.style, data.placeholder.style, properties); | ||
sticky.element.parentNode.insertBefore(data.placeholder, sticky.element); | ||
triggerEvent(sticky.element, 'stickystart'); | ||
@@ -338,3 +400,2 @@ addClass(sticky.element, sticky.settings.activeClass); | ||
cleanUp(sticky); | ||
isAdded = false; | ||
triggerEvent(sticky.element, 'stickyend'); | ||
@@ -345,10 +406,11 @@ removeClass(sticky.element, sticky.settings.activeClass); | ||
function stickToTop() { | ||
var isAdded = data.placeholder.parentNode; | ||
// The boundaries are calculated based on the element itself if it's not sticking; | ||
// otherwise the placeholder is used. | ||
boundaries = isAdded ? | ||
calculateBoundaries(sticky._placeholder, stickyMargins) : | ||
calculateBoundaries(data.placeholder, stickyMargins) : | ||
calculateBoundaries(sticky.element, stickyMargins); | ||
// Same as value || 0 | ||
var height = ~~parseFloat(window.getComputedStyle(sticky.element).height); | ||
var height = parseFloat(window.getComputedStyle(sticky.element).height) || 0; | ||
var gap = boundaries.end - height - window.pageYOffset; | ||
@@ -369,10 +431,11 @@ var isInRange = window.pageYOffset >= boundaries.start && window.pageYOffset <= boundaries.end; | ||
function stickToBottom() { | ||
var isAdded = data.placeholder.parentNode; | ||
// The boundaries are calculated based on the element itself if it's not sticking; | ||
// otherwise the placeholder is used. | ||
boundaries = isAdded ? | ||
calculateBoundaries(sticky._placeholder, stickyMargins) : | ||
calculateBoundaries(data.placeholder, stickyMargins) : | ||
calculateBoundaries(sticky.element, stickyMargins); | ||
// Same as value || 0 | ||
var height = ~~parseFloat(window.getComputedStyle(sticky.element).height); | ||
var height = parseFloat(window.getComputedStyle(sticky.element).height) || 0; | ||
var windowBottom = window.pageYOffset + window.innerHeight; | ||
@@ -406,6 +469,5 @@ var gap = boundaries.end + height - windowBottom; | ||
return function() { | ||
window.removeEventListener('resize', sticky._handlers.resize); | ||
sticky.destroy(); | ||
sticky.init(); | ||
sticky._handlers.scroll(); | ||
getData(sticky.element, 'handlers').scroll(); | ||
}; | ||
@@ -420,8 +482,23 @@ } | ||
function bindEvents(sticky) { | ||
window.addEventListener('load', sticky._handlers.scroll); | ||
window.addEventListener('scroll', sticky._handlers.scroll); | ||
window.addEventListener('resize', sticky._handlers.resize); | ||
var handlers = getData(sticky.element, 'handlers'); | ||
window.addEventListener('load', handlers.scroll); | ||
window.addEventListener('scroll', handlers.scroll); | ||
window.addEventListener('resize', handlers.resize); | ||
} | ||
/** | ||
* Unbinds the events for the sticky object provided | ||
* | ||
* @param {Sticky} sticky An instance of a Sticky object | ||
*/ | ||
function unbindEvents(sticky) { | ||
var handlers = getData(sticky.element, 'handlers'); | ||
window.removeEventListener('load', handlers.scroll); | ||
window.removeEventListener('scroll', handlers.scroll); | ||
window.removeEventListener('resize', handlers.resize); | ||
} | ||
/** | ||
* Creates a new Sticky object | ||
@@ -437,5 +514,2 @@ * | ||
this.settings = mergeSettings(options); | ||
this._placeholder = null; | ||
this._position = ''; | ||
this._handlers = {}; | ||
} | ||
@@ -450,5 +524,13 @@ | ||
Sticky.isFeatureSupported = function() { | ||
var prefixes = [ | ||
'ms', | ||
'webkit' | ||
]; | ||
var testStyle = 'position:sticky;'; | ||
var element = document.createElement('div'); | ||
element.style.cssText = 'position:sticky'; | ||
prefixes.forEach(function(prefix) { | ||
testStyle += 'position:-' + prefix + '-sticky;'; | ||
}); | ||
element.style.cssText = testStyle; | ||
@@ -465,6 +547,6 @@ return !!element.style.position; | ||
Sticky.autoInit = function(options) { | ||
options = options || defaults; | ||
var selector = options && options.selector ? options.selector : defaults.selector; | ||
[].forEach.call( | ||
document.querySelectorAll(options.selector), | ||
document.querySelectorAll(selector), | ||
function(element) { | ||
@@ -482,32 +564,27 @@ var sticky = new Sticky(element, options); | ||
Sticky.prototype.init = function() { | ||
var startPosition = this.element.getBoundingClientRect(); | ||
if (getData(this.element)) { | ||
throw new Error('This element has already been initialized'); | ||
} | ||
this._placeholder = document.createElement('div'); | ||
this._handlers.scroll = onScroll(this); | ||
this._handlers.resize = onResize(this); | ||
var placeholder = document.createElement(this.element.nodeName); | ||
this._placeholder.style.zIndex = getZIndex(this.element, this.settings.selector); | ||
setData(this.element, 'placeholder', placeholder); | ||
setData( | ||
this.element, | ||
'handlers', | ||
{ | ||
scroll: onScroll(this), | ||
resize: onResize(this) | ||
} | ||
); | ||
copyStyleProperties( | ||
this._placeholder.style, | ||
window.getComputedStyle(this.element), | ||
[ | ||
'top', | ||
'bottom', | ||
'marginTop', | ||
'marginBottom', | ||
'marginLeft', | ||
'marginRight' | ||
] | ||
placeholder.style, | ||
{ | ||
visibility: 'hidden', | ||
zIndex: getZIndex(this.element, this.settings.selector) | ||
} | ||
); | ||
copyStyleProperties( | ||
this._placeholder.style, | ||
convertNumbersToPixels(startPosition), | ||
[ | ||
'width', | ||
'height', | ||
'left' | ||
] | ||
); | ||
updatePlaceholderStyle(this); | ||
bindEvents(this); | ||
@@ -521,7 +598,4 @@ }; | ||
cleanUp(this); | ||
window.removeEventListener('scroll', this._handlers.scroll); | ||
window.removeEventListener('resize', this._handlers.resize); | ||
this._handlers = {}; | ||
this._position = ''; | ||
this._placeholder = null; | ||
unbindEvents(this); | ||
removeData(this.element); | ||
}; | ||
@@ -528,0 +602,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
95813
20
620
224