PageSourceSearch

https://www.interton.com/assets/javascript/Foundation/lazyload/index.js

js interton.com collected 2026-10-01 15:34:25 UTC 6,500 bytes, 222 lines download raw bytes

1import objectFitImages from 'object-fit-images';
2import { sitecore, MediaQuery } from '../';
3
4export class LazyLoad {
5  /* eslint-disable-next-line */
6  constructor(...opts) {
7    this._refs = {
8      elements: Array.from(
9        document.querySelectorAll(
10          '.lazy, [data-background], [data-background-xs], [data-background-sm], [data-background-md], [data-background-lg], [data-background-xl], [data-background-xxl]',
11        ),
12      ),
13    };
14
15    this._props = {
16      observer: null,
17      IE11: !!window.MSInputMethodContext && !!document.documentMode,
18      pageEditor: sitecore.isInPageEditor,
19    };
20
21    if (this._props.observer != null) {
22      this._props.observer.disconnect();
23    }
24
25    if (this._props.pageEditor) {
26      return false;
27    }
28
29    if ('IntersectionObserver' in window) {
30      const onIntersection = (entries, observer) => {
31          entries.forEach((x) => {
32            if (x.isIntersecting) {
33              this._onIntersection(x.target, (el) => {
34                observer.unobserve(el);
35              });
36            }
37          });
38        },
39        oIntersectionConfig = {
40          rootMargin: '300px 0px',
41        };
42
43      this._props.observer = new IntersectionObserver(onIntersection, oIntersectionConfig);
44      this._refs.elements.forEach((x) => this._props.observer.observe(x));
45    } else {
46      this._refs.elements.forEach((x) => {
47        this._onIntersection(x, null);
48      });
49
50      // Fallback
51      if (this._props.IE11) {
52        objectFitImages();
53      }
54    }
55  }
56
57  /**
58   * Create and append elements to watched reference
59   * @param {String} query - Selector
60   * @param {HTMLElement} base - query base (document)
61   */
62  add(query = '', base = document) {
63    if (!query.length) return false;
64
65    const arrElements = Array.from(base.querySelectorAll(query));
66
67    if (arrElements.length) {
68      this._refs.elements.push(arrElements);
69    }
70  }
71
72  /**
73   * Handler for executing load-procedure for an item
74   * @param {HTMLElement} el - Watched element
75   * @param {Function} callback - Function to execute once load has completed
76   */
77  _onIntersection(el = HTMLElement, callback = Function) {
78    /**
79     * Replace source with data attribute
80     * Remove used data attribute
81     * @param {element} el
82     * @param {string} dataSource
83     * @param {string} source
84     */
85    const addSource = (el, dataSource, source) => {
86      if (typeof el.dataset[dataSource] != 'undefined') {
87        el[source] = el.dataset[dataSource];
88        el.removeAttribute(`data-${dataSource}`);
89      }
90    };
91    switch (el.nodeName) {
92      case 'OBJECT':
93        /* eslint-disable-next-line */
94        const showImage = () => {
95          el.classList.remove('lazy');
96          el.classList.add('is-rendered');
97        };
98        /* eslint-disable-next-line */
99        const displayFallbackImage = () => {
100          const fallback = el.querySelector('img');
101          addSource(fallback, 'src', 'src');
102          showImage();
103        };
104
105        addSource(el, 'src', 'data');
106        el.addEventListener('load', showImage, false);
107        el.addEventListener('error', displayFallbackImage, false);
108        break;
109      case 'PICTURE':
110        /* eslint-disable-next-line */
111        let arrChildren = el.children,
112          intLoaded = 0;
113
114        for (let i = 0; Object.keys(arrChildren).length > i; i++) {
115          const x = arrChildren[i];
116          if (typeof x.dataset === 'undefined') continue;
117
118          if (typeof x.dataset.srcset != 'undefined') {
119            x.srcset = x.dataset.srcset;
120            x.removeAttribute('data-srcset');
121          }
122
123          if (typeof x.dataset.src != 'undefined') {
124            x.src = x.dataset.src;
125            x.removeAttribute('data-src');
126          }
127
128          if (x) {
129            x.addEventListener('load', () => {
130              x.classList.remove('lazy');
131            });
132          }
133
134          intLoaded++;
135        }
136
137        if (intLoaded > 0) {
138          if (el.classList.contains('lazy')) {
139            el.classList.remove('lazy');
140          }
141
142          el.classList.add('is-rendered');
143          if (typeof callback === 'function') {
144            callback(el);
145          }
146        }
147        break;
148      case 'IMG':
149        if (typeof el.dataset.srcset != 'undefined') {
150          el.srcset = el.dataset.srcset;
151          el.removeAttribute('data-srcset');
152        }
153
154        if (typeof el.dataset.src != 'undefined') {
155          el.src = el.dataset.src;
156          el.removeAttribute('data-src');
157        }
158
159        if (el) {
160          el.addEventListener('load', () => {
161            el.classList.remove('lazy');
162
163            const oParentEl = el.parentElement;
164            if (oParentEl.classList.contains('lazy')) {
165              el.parentElement.classList.remove('lazy');
166              el.parentElement.classList.add('is-rendered');
167            }
168          });
169        }
170        break;
171      case 'DIV':
172        /* eslint-disable-next-line */
173        const fn = (callback) => {
174          let props = {},
175            strMediaItem =
176              typeof el.dataset.background != 'undefined' ? el.dataset.background : null;
177
178          // Populate props
179          for (const i in el.dataset) {
180            if (i.indexOf('background') > -1) {
181              const key = i.replace('background', '').toLowerCase();
182              if (key != '') props[key] = el.dataset[i];
183            }
184          }
185
186          const availablePointers = Object.keys(props).sort().reverse();
187          props = this._sort(props);
188
189          availablePointers.forEach((x) => {
190            if (MediaQuery.is(x) || availablePointers.length === 1) {
191              strMediaItem = props[x];
192            }
193          });
194
195          if (strMediaItem != null) {
196            el.style.backgroundImage = 'url(' + strMediaItem + ')';
197          }
198
199          if (typeof callback == 'function') {
200            callback(el);
201          }
202        };
203
204        // OnIntersection
205        fn(callback);
206
207        // Event: MQ
208        window.addEventListener('change.mq', fn.bind(this));
209        break;
210    }
211  }
212
213  _sort(obj) {
214    return Object.keys(obj)
215      .sort()
216      .reverse()
217      .reduce(function (result, key) {
218        result[key] = obj[key];
219        return result;
220      }, {});
221  }
222}

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.