Skip to content

Instantly share code, notes, and snippets.

@colelawrence
Last active May 31, 2019 05:35
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 colelawrence/b6af1339747b6ee94eea42e37e407668 to your computer and use it in GitHub Desktop.
Save colelawrence/b6af1339747b6ee94eea42e37e407668 to your computer and use it in GitHub Desktop.
Scroll into view assistant for triggering animations and stuff
const log = console.log.bind(console);
const elts = [].slice.call(document.getElementsByClassName("siv"));
elts.forEach(elt => elt.classList.add("siv-enabled"));
elts.forEach(elt => log(elt, { offset: getOffset(elt) }));
onScroll(window, (scrollX, scrollY) => {
elts.forEach(elt => {
const top = getOffset(elt).top;
const viewHeight = window.innerHeight;
const height = elt.offsetHeight;
if (top <= (scrollY + viewHeight) && elt.__sivEntered == null) {
elt.__sivEntered = true;
elt.classList.add("siv-entered");
}
elt.classList.toggle("siv-leaving", top <= scrollY);
elt.classList.toggle("siv-entering", top <= (scrollY + viewHeight));
elt.classList.toggle("siv-offscreen-below", (top + height) < scrollY);
if (elt.__sivEntered != null) {
elt.classList.toggle("siv-offscreen-above", top > (scrollY + viewHeight));
}
})
})
function onScroll(target, fn) {
const onscroll = (_evt) => fn(target.scrollX, target.scrollY);
if (supportsPassive()) {
target.addEventListener("scroll", onscroll, { passive: true });
} else {
let timer;
addEventListener("scroll", (evt) => {
clearTimeout(timer);
timer = setTimeout(onscroll.bind(null, evt), 10);
})
}
}
function supportsPassive() {
// borrowed from modernizr
var supportsPassiveOption = false;
try {
var opts = Object.defineProperty({}, 'passive', {
get: function() {
supportsPassiveOption = true;
}
});
window.addEventListener('test', null, opts);
} catch (e) {}
return supportsPassiveOption;
}
function getOffset(elem) {
// borrowed from jQuery
// https://github.com/jquery/jquery/blob/438b1a3e8a52d3e4efd8aba45498477038849c97/src/offset.js#L68
var rect, win;
if ( !elem ) {
return;
}
// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
// Support: IE <=11+
// Running getBoundingClientRect on a
// disconnected node in IE throws an error
if ( !elem.getClientRects().length ) {
return { top: 0, left: 0 };
}
// Get document-relative position by adding viewport scroll to viewport-relative gBCR
rect = elem.getBoundingClientRect();
win = elem.ownerDocument.defaultView;
return {
top: rect.top + win.pageYOffset,
left: rect.left + win.pageXOffset
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment