PageSourceSearch

https://honnef-heute.de/wp-content/themes/foxiz/assets/js/viewport-observer.js?ver=1.0.0

js honnef-heute.de collected 2026-10-02 06:08:57 UTC 6,057 bytes, 251 lines download raw bytes

1/**
2 * RB Viewport Observer v2.3
3 * High-performance viewport detection using IntersectionObserver
4 *
5 * @package foxiz
6 * @version 2.3.0
7 */
8var RB_VIEWPORT_OBSERVER = (function (existing) {
9    'use strict';
10
11    if (existing && existing._initialized && existing._version === '2.3') {
12        return existing;
13    }
14
15    var hasIO = 'IntersectionObserver' in window;
16    var observers = {};
17    var count = 0;
18    var lastY = 0;
19    var dir = 'down';
20    var listening = false;
21    var rafId = 0;
22    var idNum = 0;
23    var win = window;
24    var doc = document;
25
26    function getScrollY() {
27        return win.pageYOffset || 0;
28    }
29
30    function onScroll() {
31        if (!rafId) {
32            rafId = requestAnimationFrame(function () {
33                var y = getScrollY();
34                var diff = y - lastY;
35                if (diff > 5) dir = 'down';
36                else if (diff < -5) dir = 'up';
37                lastY = y;
38                rafId = 0;
39            });
40        }
41    }
42
43    function startListening() {
44        if (!listening && count > 0) {
45            lastY = getScrollY();
46            win.addEventListener('scroll', onScroll, { passive: true });
47            listening = true;
48        }
49    }
50
51    function stopListening() {
52        if (listening && count === 0) {
53            win.removeEventListener('scroll', onScroll);
54            listening = false;
55            if (rafId) {
56                cancelAnimationFrame(rafId);
57                rafId = 0;
58            }
59        }
60    }
61
62    function getEl(el) {
63        return !el ? null : (el.nodeType ? el : (el[0] || null));
64    }
65
66    function parseOffset(offset, el) {
67        if (typeof offset === 'function') offset = offset.call(el);
68
69        if (typeof offset === 'number') {
70            return { m: '0px 0px ' + offset + 'px 0px', v: offset, p: false };
71        }
72
73        if (typeof offset === 'string' && offset.indexOf('%') > -1) {
74            var n = parseInt(offset, 10);
75            var v = n > 100 ? n - 100 : (n >= 0 ? -(100 - n) : n);
76            return { m: '0px 0px ' + v + '% 0px', v: v, p: true };
77        }
78
79        return { m: '0px', v: 0, p: false };
80    }
81
82    function makeCallback(id) {
83        return function (entries) {
84            var d = observers[id];
85            if (!d) return;
86
87            var e = entries[0];
88            var was = d.inView;
89            var now = e.isIntersecting;
90
91            if (was === now) return;
92            d.inView = now;
93
94            var direction = now ? dir : (dir === 'down' ? 'up' : 'down');
95
96            // Throttle continuous mode
97            if (d.cont && now) {
98                var t = Date.now();
99                if (t - d.lastT < 100) return;
100                d.lastT = t;
101            }
102
103            if (d.fn) {
104                d.fn.call(d.ctx, direction);
105            }
106
107            if (d.once && direction === 'down') {
108                unobserve(id);
109            }
110        };
111    }
112
113    function makeContext(id, el) {
114        return {
115            element: el,
116            destroy: function () { unobserve(id); },
117            reset: function () { resetState(id); }
118        };
119    }
120
121    function observe(id, opts) {
122        if (!hasIO || !opts || !opts.element) return null;
123
124        var el = getEl(opts.element);
125        if (!el) return null;
126
127        if (!id) id = 'vo_' + (++idNum);
128        if (observers[id]) unobserve(id);
129
130        var p = parseOffset(opts.offset, el);
131        var cb = makeCallback(id);
132        var ctx = makeContext(id, opts.element);
133
134        var io = new IntersectionObserver(cb, {
135            root: null,
136            rootMargin: p.m,
137            threshold: 0
138        });
139
140        observers[id] = {
141            io: io,
142            el: el,
143            fn: opts.handler,
144            ctx: ctx,
145            off: opts.offset,
146            once: !!opts.once,
147            cont: !!opts.continuous,
148            m: p.m,
149            val: p.v,
150            pct: p.p,
151            inView: false,
152            lastT: 0
153        };
154
155        count++;
156        startListening();
157        io.observe(el);
158
159        return id;
160    }
161
162    function unobserve(id) {
163        var d = observers[id];
164        if (d) {
165            d.io.disconnect();
166            d.io = d.el = d.fn = d.ctx = null;
167            delete observers[id];
168            count--;
169            stopListening();
170        }
171    }
172
173    function resetState(id) {
174        var d = observers[id];
175        if (d) {
176            d.inView = false;
177            d.lastT = 0;
178        }
179    }
180
181    function refresh(id) {
182        var d = observers[id];
183        if (!d) return;
184
185        if (!doc.body.contains(d.el)) {
186            unobserve(id);
187            return;
188        }
189
190        d.io.disconnect();
191
192        var p = parseOffset(d.off, d.el);
193        d.m = p.m;
194        d.val = p.v;
195        d.pct = p.p;
196
197        var cb = makeCallback(id);
198        var io = new IntersectionObserver(cb, {
199            root: null,
200            rootMargin: p.m,
201            threshold: 0
202        });
203
204        io.observe(d.el);
205        d.io = io;
206        d.inView = false;
207        d.lastT = 0;
208    }
209
210    function refreshAll() {
211        var ids = Object.keys(observers);
212        for (var i = 0, len = ids.length; i < len; i++) {
213            refresh(ids[i]);
214        }
215    }
216
217    function has(id) {
218        return id in observers;
219    }
220
221    function getActiveIds() {
222        return Object.keys(observers);
223    }
224
225    function destroyAll() {
226        var ids = Object.keys(observers);
227        for (var i = ids.length - 1; i >= 0; i--) {
228            unobserve(ids[i]);
229        }
230    }
231
232    function getDir() {
233        return dir;
234    }
235
236    return {
237        _initialized: true,
238        _version: '2.3',
239        observe: observe,
240        unobserve: unobserve,
241        destroy: unobserve,
242        refresh: refresh,
243        refreshAll: refreshAll,
244        resetState: resetState,
245        has: has,
246        getActiveIds: getActiveIds,
247        destroyAll: destroyAll,
248        getScrollDirection: getDir
249    };
250
251})(typeof RB_VIEWPORT_OBSERVER !== 'undefined' ? RB_VIEWPORT_OBSERVER : undefined);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.