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;
  }

})();

Kontakt

Udo Schmal
Udo Schmal

Udo Schmal
Softwareentwickler
Ellerndiek 26
24837 Schleswig
Schleswig-Holstein
Germany




+49 4621 9785538
+49 1575 0663676
+49 4621 9785539
SMS
WhatsApp

Google Maps Profile
Instagram Profile
vCard 2.1, vCard 3.0, vCard 4.0

Service Infos

CMS Info

Product Name:
UDOs Webserver
Version:
0.5.1.217
Description:
All in one Webserver
Copyright:
Udo Schmal
Compilation:
Sun, 10. Nov 2024 00:22:34

Development Info

Compiler:
Free Pascal FPC 3.3.1
compiled for:
OS:Linux, CPU:x86_64

System Info

OS:
Ubuntu 22.04.5 LTS (Jammy Jellyfish)

Hardware Info

Model:
Hewlett-Packard HP Pavilion dm4 Notebook PC
CPU Name:
Intel(R) Core(TM) i5-2430M CPU @ 2.40GHz
CPU Type:
x86_64, 1 physical CPU(s), 2 Core(s), 4 logical CPU(s),  MHz