Skip to content

Instantly share code, notes, and snippets.

@amcdnl
Created April 13, 2016 22:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save amcdnl/2cad08caef6ccb6214e5f0cfa7c0e545 to your computer and use it in GitHub Desktop.
Save amcdnl/2cad08caef6ccb6214e5f0cfa7c0e545 to your computer and use it in GitHub Desktop.
export class VisibilityObserver {
constructor(element, callback) {
this.callback = callback;
if(window.IntersectionObserver) {
this.observer = new IntersectionObserver(
::this.processChanges, { threshold: [0.5] });
this.observer.observe(element);
}
}
isVisible(boundingClientRect, intersectionRect) {
return ((intersectionRect.width * intersectionRect.height) /
(boundingClientRect.width * boundingClientRect.height) >= 0.5);
}
visibleTimerCallback(element, observer) {
delete element.visibleTimeout;
// Process any pending observations
this.processChanges(observer.takeRecords());
if ('isVisible' in element) {
delete element.isVisible;
this.callback && this.callback();
observer.unobserve(element);
}
}
processChanges(changes) {
changes.forEach((changeRecord) => {
var element = changeRecord.target;
element.isVisible = this.isVisible(changeRecord.boundingClientRect, changeRecord.intersectionRect);
if ('isVisible' in element) {
// Transitioned from hidden to visible
element.visibleTimeout = setTimeout(::this.visibleTimerCallback, 1000, element, this.observer);
} else {
// Transitioned from visible to hidden
if ('visibleTimeout' in element) {
clearTimeout(element.visibleTimeout);
delete element.visibleTimeout;
}
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment