From 2819cee144bab1adf12b6ed3e8f8067e4f3bae5f Mon Sep 17 00:00:00 2001 From: Kama Date: Wed, 13 Oct 2021 21:32:22 +0500 Subject: [PATCH] Separating lozad() loaded check when a custom load() function is specified. Unique HTML data attribute name, which contains data that lozad loaded: from `data-loaded` to `data-lozaded`. --- dist/lozad.es.js | 77 +++++++++++++++++++++++++++----------------- dist/lozad.js | 84 ++++++++++++++++++++++++++---------------------- src/lozad.js | 73 +++++++++++++++++++++++++---------------- 3 files changed, 138 insertions(+), 96 deletions(-) diff --git a/dist/lozad.es.js b/dist/lozad.es.js index 71bd7b0..78722c4 100644 --- a/dist/lozad.es.js +++ b/dist/lozad.es.js @@ -1,6 +1,6 @@ -/*! lozad.js - v1.16.0 - 2020-09-10 +/*! lozad.js - v1.16.0 - 2021-10-13 * https://github.com/ApoorvSaxena/lozad.js -* Copyright (c) 2020 Apoorv Saxena; Licensed MIT */ +* Copyright (c) 2021 Apoorv Saxena; Licensed MIT */ /** @@ -22,6 +22,7 @@ const validAttribute = ['data-iesrc', 'data-alt', 'data-src', 'data-srcset', 'da const defaultConfig = { rootMargin: '0px', threshold: 0, + checkKey: 'default', enableAutoReload: false, load(element) { if (element.nodeName.toLowerCase() === 'picture') { @@ -98,8 +99,12 @@ const defaultConfig = { loaded() {} }; -function markAsLoaded(element) { - element.setAttribute('data-loaded', true); +function getAttr (element) { + return element.getAttribute('data-lozaded') || '' +} + +function markAsLoaded (element, checkKey) { + element.setAttribute('data-lozaded', `${getAttr(element)} ${checkKey}`.trim()); } function preLoad(element) { @@ -108,26 +113,28 @@ function preLoad(element) { } } -const isLoaded = element => element.getAttribute('data-loaded') === 'true'; +function isLoaded (element, checkKey) { + return -1 !== getAttr(element).indexOf(checkKey) +} -const onIntersection = (load, loaded) => (entries, observer) => { +const onIntersection = (config) => (entries, observer) => { entries.forEach(entry => { if (entry.intersectionRatio > 0 || entry.isIntersecting) { observer.unobserve(entry.target); if (!isLoaded(entry.target)) { - load(entry.target); - markAsLoaded(entry.target); - loaded(entry.target); + config.load(entry.target); + markAsLoaded(entry.target, config.checkKey); + config.loaded(entry.target); } } }); }; -const onMutation = load => entries => { +const onMutation = config => entries => { entries.forEach(entry => { - if (isLoaded(entry.target) && entry.type === 'attributes' && validAttribute.indexOf(entry.attributeName) > -1) { - load(entry.target); + if (isLoaded(entry.target, config.checkKey) && entry.type === 'attributes' && validAttribute.indexOf(entry.attributeName) > -1) { + config.load(entry.target); } }); }; @@ -144,30 +151,40 @@ const getElements = (selector, root = document) => { return root.querySelectorAll(selector) }; +let checkKeyIncrement = 1; + function lozad (selector = '.lozad', options = {}) { - const {root, rootMargin, threshold, enableAutoReload, load, loaded} = Object.assign({}, defaultConfig, options); + // set auto-generated checkKey for custom `load` callback if checkKey is not specified + if( options.load && ! options.checkKey ){ + options.checkKey = `loadfunc${ checkKeyIncrement++ }`; + } + + let config = Object.assign({}, defaultConfig, options); let observer; let mutationObserver; if (support('IntersectionObserver')) { - observer = new IntersectionObserver(onIntersection(load, loaded), { - root, - rootMargin, - threshold + observer = new IntersectionObserver(onIntersection(config), { + root: config.root, + rootMargin: config.rootMargin, + threshold: config.threshold }); } - if (support('MutationObserver') && enableAutoReload) { - mutationObserver = new MutationObserver(onMutation(load, loaded)); + if (support('MutationObserver') && config.enableAutoReload) { + mutationObserver = new MutationObserver(onMutation(config)); } - const elements = getElements(selector, root); - for (let i = 0; i < elements.length; i++) { - preLoad(elements[i]); + // do preLoad() only for default load callback + if( 'default' === config.checkKey ){ + const elements = getElements(selector, config.root); + for (let i = 0; i < elements.length; i++) { + preLoad(elements[i]); + } } return { observe() { - const elements = getElements(selector, root); + const elements = getElements(selector, config.root); for (let i = 0; i < elements.length; i++) { if (isLoaded(elements[i])) { @@ -175,7 +192,7 @@ function lozad (selector = '.lozad', options = {}) { } if (observer) { - if (mutationObserver && enableAutoReload) { + if (mutationObserver && config.enableAutoReload) { mutationObserver.observe(elements[i], {subtree: true, attributes: true, attributeFilter: validAttribute}); } @@ -183,9 +200,9 @@ function lozad (selector = '.lozad', options = {}) { continue } - load(elements[i]); - markAsLoaded(elements[i]); - loaded(elements[i]); + config.load(elements[i]); + markAsLoaded(elements[i], config.checkKey); + config.loaded(elements[i]); } }, triggerLoad(element) { @@ -193,9 +210,9 @@ function lozad (selector = '.lozad', options = {}) { return } - load(element); - markAsLoaded(element); - loaded(element); + config.load(element); + markAsLoaded(element, config.checkKey); + config.loaded(element); }, observer, mutationObserver diff --git a/dist/lozad.js b/dist/lozad.js index f5fe826..f8741dc 100644 --- a/dist/lozad.js +++ b/dist/lozad.js @@ -1,6 +1,6 @@ -/*! lozad.js - v1.16.0 - 2020-09-10 +/*! lozad.js - v1.16.0 - 2021-10-13 * https://github.com/ApoorvSaxena/lozad.js -* Copyright (c) 2020 Apoorv Saxena; Licensed MIT */ +* Copyright (c) 2021 Apoorv Saxena; Licensed MIT */ (function (global, factory) { @@ -30,6 +30,7 @@ var defaultConfig = { rootMargin: '0px', threshold: 0, + checkKey: 'default', enableAutoReload: false, load: function load(element) { if (element.nodeName.toLowerCase() === 'picture') { @@ -106,8 +107,12 @@ loaded: function loaded() {} }; - function markAsLoaded(element) { - element.setAttribute('data-loaded', true); + function getAttr(element) { + return element.getAttribute('data-lozaded') || ''; + } + + function markAsLoaded(element, checkKey) { + element.setAttribute('data-lozaded', (getAttr(element) + ' ' + checkKey).trim()); } function preLoad(element) { @@ -116,31 +121,31 @@ } } - var isLoaded = function isLoaded(element) { - return element.getAttribute('data-loaded') === 'true'; - }; + function isLoaded(element, checkKey) { + return -1 !== getAttr(element).indexOf(checkKey); + } - var onIntersection = function onIntersection(load, loaded) { + var onIntersection = function onIntersection(config) { return function (entries, observer) { entries.forEach(function (entry) { if (entry.intersectionRatio > 0 || entry.isIntersecting) { observer.unobserve(entry.target); if (!isLoaded(entry.target)) { - load(entry.target); - markAsLoaded(entry.target); - loaded(entry.target); + config.load(entry.target); + markAsLoaded(entry.target, config.checkKey); + config.loaded(entry.target); } } }); }; }; - var onMutation = function onMutation(load) { + var onMutation = function onMutation(config) { return function (entries) { entries.forEach(function (entry) { - if (isLoaded(entry.target) && entry.type === 'attributes' && validAttribute.indexOf(entry.attributeName) > -1) { - load(entry.target); + if (isLoaded(entry.target, config.checkKey) && entry.type === 'attributes' && validAttribute.indexOf(entry.attributeName) > -1) { + config.load(entry.target); } }); }; @@ -160,40 +165,43 @@ return root.querySelectorAll(selector); }; + var checkKeyIncrement = 1; + function lozad () { var selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '.lozad'; var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var _Object$assign = Object.assign({}, defaultConfig, options), - root = _Object$assign.root, - rootMargin = _Object$assign.rootMargin, - threshold = _Object$assign.threshold, - enableAutoReload = _Object$assign.enableAutoReload, - load = _Object$assign.load, - loaded = _Object$assign.loaded; + // set auto-generated checkKey for custom `load` callback if checkKey is not specified + if (options.load && !options.checkKey) { + options.checkKey = 'loadfunc' + checkKeyIncrement++; + } + var config = Object.assign({}, defaultConfig, options); var observer = void 0; var mutationObserver = void 0; if (support('IntersectionObserver')) { - observer = new IntersectionObserver(onIntersection(load, loaded), { - root: root, - rootMargin: rootMargin, - threshold: threshold + observer = new IntersectionObserver(onIntersection(config), { + root: config.root, + rootMargin: config.rootMargin, + threshold: config.threshold }); } - if (support('MutationObserver') && enableAutoReload) { - mutationObserver = new MutationObserver(onMutation(load, loaded)); + if (support('MutationObserver') && config.enableAutoReload) { + mutationObserver = new MutationObserver(onMutation(config)); } - var elements = getElements(selector, root); - for (var i = 0; i < elements.length; i++) { - preLoad(elements[i]); + // do preLoad() only for default load callback + if ('default' === config.checkKey) { + var elements = getElements(selector, config.root); + for (var i = 0; i < elements.length; i++) { + preLoad(elements[i]); + } } return { observe: function observe() { - var elements = getElements(selector, root); + var elements = getElements(selector, config.root); for (var _i = 0; _i < elements.length; _i++) { if (isLoaded(elements[_i])) { @@ -201,7 +209,7 @@ } if (observer) { - if (mutationObserver && enableAutoReload) { + if (mutationObserver && config.enableAutoReload) { mutationObserver.observe(elements[_i], { subtree: true, attributes: true, attributeFilter: validAttribute }); } @@ -209,9 +217,9 @@ continue; } - load(elements[_i]); - markAsLoaded(elements[_i]); - loaded(elements[_i]); + config.load(elements[_i]); + markAsLoaded(elements[_i], config.checkKey); + config.loaded(elements[_i]); } }, triggerLoad: function triggerLoad(element) { @@ -219,9 +227,9 @@ return; } - load(element); - markAsLoaded(element); - loaded(element); + config.load(element); + markAsLoaded(element, config.checkKey); + config.loaded(element); }, observer: observer, diff --git a/src/lozad.js b/src/lozad.js index 9a318e3..ea287a4 100644 --- a/src/lozad.js +++ b/src/lozad.js @@ -17,6 +17,7 @@ const validAttribute = ['data-iesrc', 'data-alt', 'data-src', 'data-srcset', 'da const defaultConfig = { rootMargin: '0px', threshold: 0, + checkKey: 'default', enableAutoReload: false, load(element) { if (element.nodeName.toLowerCase() === 'picture') { @@ -93,8 +94,12 @@ const defaultConfig = { loaded() {} } -function markAsLoaded(element) { - element.setAttribute('data-loaded', true) +function getAttr (element) { + return element.getAttribute('data-lozaded') || '' +} + +function markAsLoaded (element, checkKey) { + element.setAttribute('data-lozaded', `${getAttr(element)} ${checkKey}`.trim()) } function preLoad(element) { @@ -103,26 +108,28 @@ function preLoad(element) { } } -const isLoaded = element => element.getAttribute('data-loaded') === 'true' +function isLoaded (element, checkKey) { + return -1 !== getAttr(element).indexOf(checkKey) +} -const onIntersection = (load, loaded) => (entries, observer) => { +const onIntersection = (config) => (entries, observer) => { entries.forEach(entry => { if (entry.intersectionRatio > 0 || entry.isIntersecting) { observer.unobserve(entry.target) if (!isLoaded(entry.target)) { - load(entry.target) - markAsLoaded(entry.target) - loaded(entry.target) + config.load(entry.target) + markAsLoaded(entry.target, config.checkKey) + config.loaded(entry.target) } } }) } -const onMutation = load => entries => { +const onMutation = config => entries => { entries.forEach(entry => { - if (isLoaded(entry.target) && entry.type === 'attributes' && validAttribute.indexOf(entry.attributeName) > -1) { - load(entry.target) + if (isLoaded(entry.target, config.checkKey) && entry.type === 'attributes' && validAttribute.indexOf(entry.attributeName) > -1) { + config.load(entry.target) } }) } @@ -139,30 +146,40 @@ const getElements = (selector, root = document) => { return root.querySelectorAll(selector) } +let checkKeyIncrement = 1 + export default function (selector = '.lozad', options = {}) { - const {root, rootMargin, threshold, enableAutoReload, load, loaded} = Object.assign({}, defaultConfig, options) + // set auto-generated checkKey for custom `load` callback if checkKey is not specified + if( options.load && ! options.checkKey ){ + options.checkKey = `loadfunc${ checkKeyIncrement++ }` + } + + let config = Object.assign({}, defaultConfig, options) let observer let mutationObserver if (support('IntersectionObserver')) { - observer = new IntersectionObserver(onIntersection(load, loaded), { - root, - rootMargin, - threshold + observer = new IntersectionObserver(onIntersection(config), { + root: config.root, + rootMargin: config.rootMargin, + threshold: config.threshold }) } - if (support('MutationObserver') && enableAutoReload) { - mutationObserver = new MutationObserver(onMutation(load, loaded)) + if (support('MutationObserver') && config.enableAutoReload) { + mutationObserver = new MutationObserver(onMutation(config)) } - const elements = getElements(selector, root) - for (let i = 0; i < elements.length; i++) { - preLoad(elements[i]) + // do preLoad() only for default load callback + if( 'default' === config.checkKey ){ + const elements = getElements(selector, config.root) + for (let i = 0; i < elements.length; i++) { + preLoad(elements[i]) + } } return { observe() { - const elements = getElements(selector, root) + const elements = getElements(selector, config.root) for (let i = 0; i < elements.length; i++) { if (isLoaded(elements[i])) { @@ -170,7 +187,7 @@ export default function (selector = '.lozad', options = {}) { } if (observer) { - if (mutationObserver && enableAutoReload) { + if (mutationObserver && config.enableAutoReload) { mutationObserver.observe(elements[i], {subtree: true, attributes: true, attributeFilter: validAttribute}) } @@ -178,9 +195,9 @@ export default function (selector = '.lozad', options = {}) { continue } - load(elements[i]) - markAsLoaded(elements[i]) - loaded(elements[i]) + config.load(elements[i]) + markAsLoaded(elements[i], config.checkKey) + config.loaded(elements[i]) } }, triggerLoad(element) { @@ -188,9 +205,9 @@ export default function (selector = '.lozad', options = {}) { return } - load(element) - markAsLoaded(element) - loaded(element) + config.load(element) + markAsLoaded(element, config.checkKey) + config.loaded(element) }, observer, mutationObserver