IntersectionObserver und ResizeObserver Polyfill

Da alte Browser wie der Internet Explorer oder auch der frühe Edge den IntersectionObserver oder ResizeObserver noch nicht zur Verfügung stellen muss für diese Browser noch jeweils ein Polyfill her.

Dies ist nur ein unvollständiger Polyfill, jedoch reicht er für all meine Scripte die ich auf dieser Website veröffentliche.

IntersectionObserver JavaScript (3,54 kByte) 24.12.2021 12:59
// coding: utf-8
/** Created by: Udo Schmal | https://www.gocher.me/ */
(function () {
  'use strict';

  // minimum IntersectionObserver polyfill (options are ignored)
  if (('IntersectionObserver' in window)) {
    let IntersectionObserver = function(callback, options) {
      var self = this;
      // mutation observer object
      var domObserver = null;
      // array for obsered elements
      var observables = [];
      // trigger status
      var active = false;
      // trigger elements to check if intersecting
      function trigger(target) {
        let els = target ? [ target ] : observables, len = els.length, entries = [];
        for (let i = 0; i < len; i++) {
          let rect = els[i].getBoundingClientRect();
          let intersecting = (rect.top <= window.innerHeight && rect.top >= -rect.height &&
              rect.left <= window.innerWidth && rect.left >= -rect.width &&
              !!(els[i].offsetWidth || els[i].offsetHeight || els[i].getClientRects().length));
          if (intersecting || els[i].dataset.intersecting != intersecting+'') {
            entries.push({time: performance.now(), target: els[i], boundingClientRect: rect, isIntersecting: intersecting});
            els[i].dataset.intersecting = intersecting;
          }
        }
        // execute callback with array of intersecting entries and reference to the observer
        callback.apply(self, [entries, self]);
        // reset ticking
        active = false;
      }
      function debounceTrigger() {
        if (!active) {
          active = true;
          window.requestAnimationFrame(trigger.bind(window, null));
        }
      }

      // Watch for intersection events on a specific target Element.
      this.observe = function(target) {
        if (target instanceof window.Element) {
          // add listeners and mutation observers on start observing the first element
          if (observables.length === 0) {
            connect();
          }
          // don't add already observed targets
          var index = observables.indexOf(target);
          if (index === -1) {
            observables.push(target);
          }
          // trigger in case element is already visible
          trigger(target);
        }
      };

      // Stop watching for intersection events on a specific target Element.
      this.unobserve = function(target) {
        if (target instanceof window.Element) {
          var index = observables.indexOf(target);
          if (index !== -1) {
            observables.splice(index, 1);
          }
          // remove listeners and mutation observers if no element left
          if (observables.length === 0) {
            this.disconnect();
          }
        }
      };

      // start observing
      function connect () {
        document.addEventListener('scroll', debounceTrigger);
        window.addEventListener('resize', debounceTrigger);
        domObserver = new MutationObserver(debounceTrigger);
        domObserver.observe(document, {
          attributes: true,
          childList: true,
          characterData: true,
          subtree: true
        });
      }

      // Stop observing threshold events on all target elements.
      this.disconnect = function() {
        document.removeEventListener('scroll', debounceTrigger);
        window.removeEventListener('resize', debounceTrigger);
        domObserver.disconnect();
      };
    };

    // expose constructor globally
    window.IntersectionObserver = IntersectionObserver;
  }

})();

Auch dies ist nur ein unvollständiger Polyfill, aber auch hier reicht er für all meine Scripte die ich auf dieser Website veröffentliche.

ResizeObserver JavaScript (3,1 kByte) 24.12.2021 12:59
// coding: utf-8
/** Created by: Udo Schmal | https://www.gocher.me/ */
(function () {
  'use strict';

  // minimum ResizeObserver polyfill
  if (!('ResizeObserver' in window)) {
    let ResizeObserver = function(callback) {
      // mutation observer object
      var domObserver = null;
      // array for obsered elements
      var observables = [];
      var rects = [];
      // trigger status
      var active = false;
      // trigger elements to check if intersecting
      function trigger(target) {
        let els = target ? [ target ] : observables, len = els.length, entries = [];
        for (let i = 0; i < len; i++) {
          let rect = els[i].getBoundingClientRect();
          if (!rects[i] || rects[i].width != rect.width || rects[i].height != rects.height) {
            if (!rects[i]) {
              rects.push(rect);
            } else {
              rects.splice(i, 1, rect);
            }
            entries.push({target: els[i], contentRect: rect});
          }
        }
        // execute callback with array of intersecting entries and reference to the observer
        callback.apply(self, [entries, self]);
        // reset ticking
        active = false;
      }
      function debounceTrigger() {
        if (!active) {
          active = true;
          window.requestAnimationFrame(trigger.bind(window, null));
        }
      }

      // Watch for resize events on a specific target Element.
      this.observe = function(target) {
        if (target instanceof window.Element) {
          // add listeners and mutation observers on start observing the first element
          if (observables.length === 0) {
            connect();
          }
          elements.push(target);
          // trigger in case element is already visible
          trigger(target);
        }
      };

      // Stop watching for resize events on a specific target Element.
      this.unobserve = function(target) {
        if (target instanceof window.Element) {
          var index = elements.indexOf(target);
          if (index !== -1) {
            elements.splice(index, 1);
          }
          // remove listeners and mutation observers if no element left
          if (observables.length === 0) {
            this.disconnect();
          }
        }
      };

      // start observing
      function connect() {
        document.addEventListener('transitionend', debounceTrigger);
        window.addEventListener('resize', debounceTrigger);
        domObserver = new MutationObserver(debounceTrigger);
        domObserver.observe(document, {
          attributes: true,
          childList: true,
          characterData: true,
          subtree: true
        });
      };

      // Stop observing threshold events on all target elements.
      this.disconnect = function() {
        document.removeEventListener('transitionend', debounceTrigger);
        window.removeEventListener('resize', debounceTrigger);
        domObserver.disconnect();
      };
    };

    // expose constructor globally
    window.ResizeObserver = ResizeObserver;
  }

})();

Author: , published: , last modified:

Kontakt

Udo Schmal

Udo Schmal
Softwareentwickler
Olvengraben 41
47608 Geldern
Nordrhein-Westfalen
Germany





+49 2831 9776557
+49 1575 0663676
+49 2831 1328709
SMS
WhatsApp

Google Maps Profile
Instagram Profile
vCard 3.0

Service Infos

CMS Info Product Name:
UDOs Webserver
Version:
0.5.0.122
Description:
All in one Webserver
Copyright:
Udo Schmal
Compilation:
Fri, 14. Jan 2022 21:55:59
Development Info Compiler:
Free Pascal FPC 3.3.1
compiled for:
OS:Linux, CPU:x86_64
System Info OS:
Ubuntu 20.04.3 LTS (Focal Fossa)
Hardware Info Model:
Hewlett-Packard HP Pavilion dv7 Notebook PC
CPU Name:
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
CPU Type:
x86_64, 1 physical CPU(s), 2 Core(s), 4 logical CPU(s), 1600.000 MHz