Current Path : /var/www/www-root/data/www/www.monolith-realty.ru/bitrix/js/main/lazyload/src/ |
Current File : /var/www/www-root/data/www/www.monolith-realty.ru/bitrix/js/main/lazyload/src/lazyload.js |
import {Type} from 'main.core'; import 'main.polyfill.intersectionobserver'; const LazyLoad = { observer: null, images: {}, imageStatus: { hidden: -2, error: -1, "undefined": 0, inited: 1, loaded: 2 }, imageTypes: { image: 1, background: 2 }, initObserver: function() { this.observer = new IntersectionObserver(this.onIntersection.bind(this), { rootMargin: '20% 0% 20% 0%', threshold: 0.10 }); }, onIntersection: function(entries) { entries.forEach(function (entry) { if (entry.isIntersecting) { this.showImage(entry.target); } }.bind(this)); }, registerImage: function(id, isImageVisibleCallback, options) { if (this.observer === null) { this.initObserver(); } options = options || {}; if (!Type.isStringFilled(id)) { return; } if (Type.isObject(this.images[id])) { return; } const element = document.getElementById(id); if (!Type.isDomNode(element)) { return; } this.observer.observe(element); this.images[id] = { id: id, node: null, src: null, dataSrcName: options.dataSrcName || 'src', type: null, func: Type.isFunction(isImageVisibleCallback) ? isImageVisibleCallback : null, status: this.imageStatus.undefined }; }, registerImages: function(ids, isImageVisibleCallback, options) { if (Type.isArray(ids)) { for (let i = 0, length = ids.length; i < length; i++) { this.registerImage(ids[i], isImageVisibleCallback, options); } } }, showImage: function(imageNode) { const imageNodeId = imageNode.id; if (!Type.isStringFilled(imageNodeId)) { return; } let image = this.images[imageNodeId]; if (!Type.isPlainObject(image)) { return; } if (image.status == this.imageStatus.undefined) { this.initImage(image); } if (image.status !== this.imageStatus.inited) { return; } if ( !image.node || !image.node.parentNode ) { image.node = null; image.status = this.imageStatus.error; return; } if (image.type == this.imageTypes.image) { image.node.src = image.src; } else { image.node.style.backgroundImage = "url('" + image.src + "')"; } image.node.dataset[image.dataSrcName] = ""; image.status = this.imageStatus.loaded; }, showImages: function(checkOwnVisibility) { checkOwnVisibility = (checkOwnVisibility !== false); for (let id in this.images) { if (!this.images.hasOwnProperty(id)) { continue; } let image = this.images[id]; if (image.status == this.imageStatus.undefined) { this.initImage(image); } if (image.status !== this.imageStatus.inited) { continue; } if ( !image.node || !image.node.parentNode ) { image.node = null; image.status = this.imageStatus.error; continue; } let isImageVisible = true; if ( checkOwnVisibility && Type.isFunction(image.func) ) { isImageVisible = image.func(image); } if ( isImageVisible === true && this.isElementVisibleOnScreen(image.node) ) { if (image.type == this.imageTypes.image) { image.node.src = image.src; } else { image.node.style.backgroundImage = "url('" + image.src + "')"; } image.node.dataset[image.dataSrcName] = ""; image.status = this.imageStatus.loaded; } } }, initImage: function(image) { image.status = this.imageStatus.error; const node = document.getElementById(image.id); if (!Type.isDomNode(node)) { return; } const src = node.dataset[image.dataSrcName]; if (Type.isStringFilled(src)) { image.node = node; image.src = src; image.status = this.imageStatus.inited; image.type = (image.node.tagName.toLowerCase() == "img" ? this.imageTypes.image : this.imageTypes.background ); } }, isElementVisibleOnScreen: function (element) { const coords = this.getElementCoords(element); const windowTop = window.pageYOffset || document.documentElement.scrollTop; const windowBottom = windowTop + document.documentElement.clientHeight; coords.bottom = coords.top + element.offsetHeight; return ( (coords.top > windowTop && coords.top < windowBottom) // topVisible || (coords.bottom < windowBottom && coords.bottom > windowTop) // bottomVisible ); }, isElementVisibleOn2Screens: function(element) { const windowHeight = document.documentElement.clientHeight; var windowTop = window.pageYOffset || document.documentElement.scrollTop; var windowBottom = windowTop + windowHeight; var coords = this.getElementCoords(element); coords.bottom = coords.top + element.offsetHeight; windowTop -= windowHeight; windowBottom += windowHeight; return ( (coords.top > windowTop && coords.top < windowBottom) // topVisible || (coords.bottom < windowBottom && coords.bottom > windowTop) // bottomVisible ); }, getElementCoords: function(element) { const box = element.getBoundingClientRect(); return { originTop: box.top, originLeft: box.left, top: box.top + window.pageYOffset, left: box.left + window.pageXOffset }; }, onScroll: function() { }, clearImages: function () { this.images = []; } }; export {LazyLoad};