code: function OnScreen(options = { tolerance: 0, debounce: 100, container: window }) {
      this.options = {};
      this.trackedElements = {};
  
      Object.defineProperties(this.options, {
          container: {
              configurable: false,
              enumerable: false,
              get() {
                  let container;
  
                  if (typeof options.container === 'string') {
                      container = document.querySelector(options.container);
                  } else if (options.container instanceof HTMLElement) {
                      container = options.container;
                  }
  
                  return container || window;
              },
              set(value) {
                  options.container = value;
              }
          },
          debounce: {
              get() {
                  return parseInt(options.debounce, 10) || 100;
              },
              set(value) {
                  options.debounce = value;
              }
          },
          tolerance: {
              get() {
                  return parseInt(options.tolerance, 10) || 0;
              },
              set(value) {
                  options.tolerance = value;
              }
          }
      });
  
      Object.defineProperty(this, '_scroll', {
          enumerable: false,
          configurable: false,
          writable: false,
          value: this._debouncedScroll.call(this)
      });
  
      observeDOM(document.querySelector('body'), () => {
          Object.keys(this.trackedElements).forEach((element) => {
              this.on('enter', element);
              this.on('leave', element);
          });
      });
  
      this.attach();
  }
docs: Detects wether DOM nodes enter or leave the viewport
  
  @constructor
  @param {object} options The configuration object