intersectionobserver root example

Example 1: IntersectionObserver

var options = {
  root: document.querySelector('#scrollArea'),
  rootMargin: '0px',
  threshold: 1.0
}

var observer = new IntersectionObserver(callback, options);

Example 2: intersectionobserver

// super class that can be mixed into any JS class based object
// in order to add an intersection / visibility observer to it
// example code is for adding to a web component (LitElement optimized)
const IntersectionObserverMixin = function (SuperClass) {
  // SuperClass so we can write any web component library / base class
  return class extends SuperClass {
    /**
     * Constructor
     */
    constructor() {
      super();
      // listen for this to be true in your element
      this.elementVisible = false;
      // threasholds to check for, every 25%
      this.IOThresholds = [0.0, 0.25, 0.5, 0.75, 1.0];
      // margin from root element
      this.IORootMargin = "0px";
      // wait till at least 50% of the item is visible to claim visible
      this.IOVisibleLimit = 0.5;
      // drop the observer once we are visible
      this.IORemoveOnVisible = true;
      // delay in observing, performance reasons for minimum at 100
      this.IODelay = 100;
    }
    /**
     * Properties, LitElement format
     */
    static get properties() {
      let props = {};
      if (super.properties) {
        props = super.properties;
      }
      return {
        ...props,
        elementVisible: {
          type: Boolean,
          attribute: "element-visible",
          reflect: true,
        },
      };
    }
    /**
     * HTMLElement specification
     */
    connectedCallback() {
      if (super.connectedCallback) {
        super.connectedCallback();
      }
      // setup the intersection observer, only if we are not visible
      if (!this.elementVisible) {
        this.intersectionObserver = new IntersectionObserver(
          this.handleIntersectionCallback.bind(this),
          {
            root: document.rootElement,
            rootMargin: this.IORootMargin,
            threshold: this.IOThresholds,
            delay: this.IODelay,
          }
        );
        this.intersectionObserver.observe(this);
      }
    }
    /**
     * HTMLElement specification
     */
    disconnectedCallback() {
      // if we have an intersection observer, disconnect it
      if (this.intersectionObserver) {
        this.intersectionObserver.disconnect();
      }
      if (super.disconnectedCallback) {
        super.disconnectedCallback();
      }
    }
    /**
     * Very basic IntersectionObserver callback which will set elementVisible to true
     */
    handleIntersectionCallback(entries) {
      for (let entry of entries) {
        let ratio = Number(entry.intersectionRatio).toFixed(2);
        // ensure ratio is higher than our limit before trigger visibility
        if (ratio >= this.IOVisibleLimit) {
          this.elementVisible = true;
          // remove the observer if we've reached our target of being visible
          if (this.IORemoveOnVisible) {
            this.intersectionObserver.disconnect();
          }
        }
      }
    }
  };
};