Skip to content

Instantly share code, notes, and snippets.

@stramel
Last active March 18, 2019 16:10
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 stramel/8b8f68dd7a0e1839f71bd259069fd172 to your computer and use it in GitHub Desktop.
Save stramel/8b8f68dd7a0e1839f71bd259069fd172 to your computer and use it in GitHub Desktop.
[WIP] IntersectionObserver element
class MyIntersectionObserver extends HTMLElement {
constructor() {
super();
this._observer = null;
this._visited = false;
this._root = null;
this._rootMargin = '0px';
this._threshold = 0;
this._shadowRoot = this.attachShadow({ mode: 'open' });
this._template = this.children[0];
}
connectedCallback() {
// this.style.display = 'block';
this._buildObserver();
}
disconnectedCallback() {
this._unobserve();
}
// get root() {
// return this._root;
// }
// set root(v) {
// this.root = v;
// this._buildObserver();
// }
// get rootMargin() {
// return this._rootMargin;
// }
// set rootMargin(v) {
// this._rootMargin = v;
// this._buildObserver();
// }
get threshold() {
return this._threshold;
}
set threshold(v) {
this._threshold = v;
this._buildObserver();
}
_unobserve() {
if (this._observer) {
if (this._observer.disconnect) {
this._observer.disconnect();
} else if (this._observer.unobserve) {
this._observer.unobserve(this);
}
}
}
_observe([entry]) {
console.log(entry.isIntersecting, entry.intersectionRatio);
if (entry.isIntersecting) {
this.dispatchEvent(new CustomEvent('enter', { detail: entry }));
if (this._template && !this._visited) {
this._shadowRoot.appendChild(document.importNode(this._template.content, true));
}
this._visited = true;
} else if (this._visited) {
this.dispatchEvent(new CustomEvent('leave', { detail: entry }));
}
}
_buildObserver() {
if (this._observer) {
this._unobserve();
}
this._observer = new IntersectionObserver(this._observe.bind(this), {
root: this.root,
rootMargin: this.rootMargin,
threshold: this.threshold,
});
this._observer.observe(this);
}
// Respond to attribute changes.
static get observedAttributes() {
return ['root', 'root-margin', 'threshold'];
}
attributeChangedCallback(attr, oldValue, newValue) {
const prop = attr.replace(/-([a-z])/gi, g => g[1].toUpperCase());
if ((oldValue || this[prop]) !== newValue) this[prop] = newValue;
}
}
customElements.define('int-obs', MyIntersectionObserver);
@stramel
Copy link
Author

stramel commented Feb 12, 2019

TODO:

  • Properly handle margin/offset
  • Check other react-waypoint stuff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment