Skip to content

Instantly share code, notes, and snippets.

@aarongeorge
Created December 16, 2016 04:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aarongeorge/9f9c1a124e8d9bc146d6767b11ca1220 to your computer and use it in GitHub Desktop.
Save aarongeorge/9f9c1a124e8d9bc146d6767b11ca1220 to your computer and use it in GitHub Desktop.
JS Module for abstracted scrolling
// Constructor: AbstractedScroll
var AbstractedScroll = function (options) {
'use strict';
// Store reference to `container`
this.container = options.container;
// Call `enable`
this.enable();
};
// Method: enable
AbstractedScroll.prototype.enable = function () {
'use strict';
// Set body height
document.body.style.height = this.getElAbsolutePosition(document.body).height + 'px';
// Scroll `container`
this.scrollTo(window.scrollX, window.scrollY);
// Fix `container`
this.container.style.position = 'fixed';
// Bind scroll event
window.addEventListener('scroll', this, {
'passive': true
});
};
// Method: disable
AbstractedScroll.prototype.disable = function () {
'use strict';
// Set body height
document.body.style.height = 'auto';
// Reset `container` position
this.scrollTo(0, 0);
// Unfix `container`
this.container.style.position = 'static';
// Unbind scroll event
window.removeEventListener('scroll', this);
};
// Method: scrollTo
AbstractedScroll.prototype.scrollTo = function (x, y) {
'use strict';
// Default `x` and `y` to `0` if they aren't numbers
x = isNaN(x) ? 0 : x;
y = isNaN(y) ? 0 : y;
// Translate `container` to `x` and `y`
this.container.style.transform = 'translate3d(' + -x + 'px, ' + -y + 'px, 0)';
};
// Method: handleEvent
AbstractedScroll.prototype.handleEvent = function () {
'use strict';
// Call `requestTick`
this.requestTick();
};
// Method: requestTick
AbstractedScroll.prototype.requestTick = function () {
'use strict';
// Currently not ticking
if (!this.ticking) {
// Call `scrollHandler`
requestAnimationFrame(this.scrollHandler.bind(this));
}
// Set `ticking` to `true`
this.ticking = true;
};
// Method: scrollHandler
AbstractedScroll.prototype.scrollHandler = function () {
'use strict';
// Call `scrollTo`
this.scrollTo(window.scrollX, window.scrollY);
// Set `ticking` to `false`
this.ticking = false;
};
// Method: bindScrollEvent
AbstractedScroll.prototype.bindScrollEvent = function () {
'use strict';
window.addEventListener('scroll', this, {
'passive': true
});
};
// Method: destroy
AbstractedScroll.prototype.destroy = function () {
'use strict';
};
// Method: getElAbsolutePosition
AbstractedScroll.prototype.getElAbsolutePosition = function (el) {
'use strict';
// Cache bounding client rect of `el`
var boundingRect = el.getBoundingClientRect();
// Return object with absolute position values
return {
'bottom': boundingRect.bottom + window.scrollY,
'height': boundingRect.height,
'left': boundingRect.left + window.scrollX,
'right': boundingRect.right + window.scrollX,
'top': boundingRect.top + window.scrollY,
'width': boundingRect.width
};
};
// Export `AbstractedScroll`
module.exports = AbstractedScroll;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment