Skip to content

Instantly share code, notes, and snippets.

@MoOx
Created August 6, 2014 14:19
Show Gist options
  • Save MoOx/a7ac34844dcd3591f1be to your computer and use it in GitHub Desktop.
Save MoOx/a7ac34844dcd3591f1be to your computer and use it in GitHub Desktop.
{position: sticky} draft
/**
* Module dependencies
*/
// nothing yet
/**
* Constantes
*/
var PREFIXES = ["webkit", "moz", "ms"]
/**
* locals variables
*/
var toObserve = []
var observableLoop = false
/**
* Expose module
*
* @type {Function}
*/
module.exports = PositionSticky
/**
* Polyfill CSS {position: sticky}
*/
function PositionSticky(obj, options) {
if(!(this instanceof PositionSticky)) {
return PositionSticky.apply(Object.create(PositionSticky.prototype), arguments)
}
this.elements = toArray(typeof obj === "string" ? document.querySelectorAll(obj) : obj)
this.elements.forEach(observeElement)
// start observable loop if not already done (& if it's useful)
if (!observableLoop && toObserve.length > 1) {
observe()
}
else {
if (console && console.log) {
console.log("PositionSticky: Nothing to observe yet")
}
}
}
/**
* Apply CSS {position: sticky} polyfill to an Element
*
* @param {Element} el DOM Element to apply the fix
*/
function observeElement(el) {
if (!el.style) {
throw Error("Element '" + el + "' doesn't have a `style` property. Polyfill cannot be applied.")
}
if (el.style.position && el.style.position.indexOf("sticky") !== -1) {
console.log("sticky already detected for ", el)
}
else {
console.log("sticky polyfill activated for ", el)
var toObserve.push(el)
}
}
/**
* Returns true if the given element is visible
*
* @param {Object} el element to check
*/
function isVisible(el) {
var rect = el.getBoundingClientRect()
var windowHeight = window.innerHeight || document.documentElement.clientHeight
return rect.bottom > 0 && rect.top < windowHeight
}
/**
* Observe all element & apply/remove sticky fix
*
* @return void
*/
function observe() {
toObserve.forEach(updateElement)
// loop
requestAnimationFrame(observe)
}
function updateElement(el) {
// apply fix
if (isVisible(el)) {
console.log("apply fix")
stick(el)
}
// remove fix
else {
console.log("remove fix")
unstick(el)
}
}
/**
* apply sticky fix on an element
*/
function stick(el) {
createGost(el)
// things
}
/**
* apply sticky fix on an element
*/
function stick(el) {
// remove things
}
/**
* create gost of an element
*/
function createGost(el) {
// clone to create a gost
}
/**
* Transform argument to an array
*
* @param {Object} els a array like collection
*/
var toArray = function(els) {
return Array.prototype.slice.call(els)
}
// IE < 9 support (slice doesn't work on dom elements)
// so we try one shot, & use an old school method otherwise
try {
toArray(document.documentElement)
}
catch (e) {
toArray = function(els) {
var i
var a = []
for (i = 0; i < els.length; i++) {
a.push(els[i])
}
}
}
/**
* check CSS {position: sticky} support
*/
function checkStickySupport() {
var prop = "position:"
var value = "sticky"
var el = document.createElement('div')
el.style.cssText = prop + PREFIXES.join(value + ";" + prop).slice(0, -prop.length)
return el.style.position.indexOf(value) !== -1
})
/**
* requestAnimationFrame
*/
var requestAnimationFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60)
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment