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.
// 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.
// 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;
}
})();