diff --git a/README.md b/README.md
index 0158886..f0bcdbb 100644
--- a/README.md
+++ b/README.md
@@ -1,75 +1,102 @@
# Responsively Lazy
-**The best lazy loading implementation available.**
+**Probably the best lazy loading implementation available.**
-- Handles responsive images
+- Perfect for responsive images
- Truly lazy (absolutely no unnecessary requests)
- **SEO friendly** (valid HTML)
-- Supports [WebP](https://en.wikipedia.org/wiki/WebP)
+- Supports [WebP](https://en.wikipedia.org/wiki/WebP) and [AVIF](https://en.wikipedia.org/wiki/AVIF)
+- Customizable load threshold
+- Lazy load HTML
-
+
-You can find a demo at [http://ivopetkov.github.io/responsivelyLazy/](http://ivopetkov.github.io/responsivelyLazy/) and learn how the magic works at [http://ivopetkov.com/b/lazy-load-responsive-images/](http://ivopetkov.com/b/lazy-load-responsive-images/)
+You can find a demo at [ivopetkov.github.io/responsively-lazy-v3/](https://ivopetkov.github.io/responsively-lazy-v3/) and learn how the magic works at [ivopetkov.com/responsively-lazy/](https://ivopetkov.com/responsively-lazy/)
## Download and install
-Download the minified [css](https://raw.githubusercontent.com/ivopetkov/responsively-lazy/master/responsivelyLazy.min.css) and [js](https://raw.githubusercontent.com/ivopetkov/responsively-lazy/master/responsivelyLazy.min.js) files or install through [npm](https://www.npmjs.com/) and [bower](http://bower.io/)
+Download the minified [JS file](https://raw.githubusercontent.com/ivopetkov/responsively-lazy/master/responsively-lazy.min.js) or install via [npm](https://www.npmjs.com/).
```
npm install responsively-lazy
```
+
+The library does not have any dependencies, and it's just 2.5kb when gzipped and minified.
+
+## Usage
+
+* Include the JS file in the head of the document
+```html
+
```
-bower install responsively-lazy
+
+* Add the following code for each image
+```html
+
```
+Values to customize:
-The library does not have any dependencies, and it's just 1.1kb gzipped and minified.
+**aspect-ratio**
-## Usage
+The aspect ratio of the image (width/height) to reserve space. Skip if you don't know it.
+
+**src**
+
+The default (largest) image size. Will be used by very old browsers, search engines, social networks, etc.
+
+**data-responsively-lazy** (the star of the show)
+
+Must contain a list of image versions separated by commas. Each version must contain a path to the image and its size. Optionaly you can specify the file type (webp or avif). The first supported format for the selected width is used.
-* Include the css file in the head tag
```html
-
+data-responsively-lazy="images/400.avif 400w avif, images/400.webp 400w webp, images/400.jpg 400w, ..."
```
-* Include the js file right before the end of the body tag
+**data-responsively-lazy-threshold**
+
+Specify how close to the viewport an image should be to start loading.
```html
-
+data-responsively-lazy-threshold="500px" // can use percents too
```
-* Add the following code for each image
+**data-responsively-lazy-type=html**
+
+Lazy load HTML. Can contain JavaScript.
+
```html
-
-
-
+
```
-The things to customize are the **padding-bottom** style, and the values of the **src** and **data-srcset** attributes. If you don't know the image aspect ratio you can skip the div tag and move the responsively-lazy class to te img tag:
+
+**data-responsively-lazy-type=background**
+
+Lazy load image as a background image.
+
```html
-
+
```
-You can list image versions in the [WebP format](https://en.wikipedia.org/wiki/WebP) which will be used if the browser supports it.
## A new concept
-Responsively Lazy is very different from the other lazy loading libraries. They make you break your HTML by removing the `src` attribute, or make you put tiny version there or make you use `` to make your images appear in Google Images. The following code has worked for ages:
+Responsively Lazy is very different from the other lazy loading libraries. Others make you break your HTML by removing the `src` attribute, or make you put some tiny version there, or make you use `` to make your images appear in search engines (like Google Images). The following code has worked for ages:
```html
```
Let's not break it when we can enhance it.
```html
-
+
```
## Browser support
-The lazy loading works in browsers supporting the srcset attribute. As of December 2017 that's [86.78%](http://caniuse.com/#feat=srcset). Unsupported browsers will load the image in the src attribute. That's the image search engines and social networks will find, so it's better to make it high resolution.
+The lazy loading works in browsers supporting the srcset attribute and JavaScript. As of December 2023 that's [97.6%](https://caniuse.com/#feat=srcset). Unsupported browsers will load the image in the src attribute. That's the image search engines and social networks will find, so it's better to make it high resolution.
## DOM changes
The library will listen for DOM changes and you can also trigger visible images loading by calling `responsivelyLazy.run()`.
## License
-Free to use under the [MIT license](http://opensource.org/licenses/MIT).
+Free to use under the [MIT license](https://opensource.org/licenses/MIT).
## Got questions?
-You can find me at [@IvoPetkovCom](https://twitter.com/IvoPetkovCom) and [ivopetkov.com](http://ivopetkov.com)
+You can find me at [@IvoPetkovCom](https://twitter.com/IvoPetkovCom) and [ivopetkov.com](https://ivopetkov.com)
diff --git a/bower.json b/bower.json
deleted file mode 100644
index db51213..0000000
--- a/bower.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "name": "responsively-lazy",
- "description": "Lazy load responsive images",
- "homepage": "http://ivopetkov.com/b/lazy-load-responsive-images/",
- "authors": [
- {
- "name": "Ivo Petkov",
- "email": "ivo@ivopetkov.com",
- "homepage": "http://ivopetkov.com/"
- }
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/ivopetkov/responsively-lazy.git"
- },
- "bugs": {
- "url": "https://github.com/ivopetkov/responsively-lazy/issues"
- },
- "keywords": [
- "images",
- "lazyload",
- "responsive",
- "seo"
- ],
- "license": "MIT"
-}
\ No newline at end of file
diff --git a/package.json b/package.json
index 408c192..d480260 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "responsively-lazy",
"title": "Responsively Lazy",
- "version": "2.0.2",
+ "version": "3.0.0",
"description": "Lazy load responsive images",
"homepage": "http://ivopetkov.com/b/lazy-load-responsive-images/",
"author": {
diff --git a/responsively-lazy.js b/responsively-lazy.js
new file mode 100644
index 0000000..29647b8
--- /dev/null
+++ b/responsively-lazy.js
@@ -0,0 +1,466 @@
+/*
+ * Responsively Lazy
+ * https://ivopetkov.com/responsively-lazy/
+ * Copyright (c) Ivo Petkov
+ * Free to use under the MIT license.
+ *
+ * Debug:
+ * document.cookie = "ivopetkov-responsively-lazy=debug";
+*/
+
+var responsivelyLazy = typeof responsivelyLazy !== 'undefined' ? responsivelyLazy : (function () {
+
+ if (typeof window.addEventListener !== 'undefined' && typeof document.querySelectorAll !== 'undefined') { // Check for old browsers
+
+ var debug = document.cookie.indexOf('ivopetkov-responsively-lazy=debug') !== -1;
+
+ var hasWebPSupport = null;
+ var hasAVIFSupport = null;
+ var hasSrcSetSupport = 'srcset' in document.createElement('img');
+ var windowWidth = null;
+ var windowHeight = null;
+ var hasIntersectionObserverSupport = typeof IntersectionObserver !== 'undefined';
+ var mutationObserverIsDisabled = false;
+
+ var getVisibilityPriority = function (element) {
+ var thresholdHorizontal = 0;
+ var thresholdVertical = 0;
+ var thresholdValue = element.getAttribute('data-responsively-lazy-threshold');
+ if (thresholdValue !== null) {
+ if (thresholdValue.substr(-2) === 'px') {
+ thresholdHorizontal = thresholdVertical = parseInt(thresholdValue.substr(0, thresholdValue.length - 2), 10);
+ } else if (thresholdValue.substr(-1) === '%') {
+ var percent = parseInt(thresholdValue.substr(0, thresholdValue.length - 1), 10) / 100;
+ thresholdHorizontal = Math.floor(windowWidth * percent);
+ thresholdVertical = Math.floor(windowHeight * percent);
+ }
+ }
+ var rect = element.getBoundingClientRect();
+ var elementTop = rect.top;
+ var elementLeft = rect.left;
+ var elementWidth = rect.width;
+ var elementHeight = rect.height;
+
+ var getVisiblitySize = function (elementPoint, elementSize, windowSize) {
+ return elementPoint < windowSize && elementPoint + elementSize > 0 ? Math.min(windowSize, elementPoint + elementSize) - Math.max(0, elementPoint) : 0;
+ };
+
+ var percent = (getVisiblitySize(elementLeft, elementWidth, windowWidth) * getVisiblitySize(elementTop, elementHeight, windowHeight)) / (elementWidth * elementHeight) * 100;
+ if (percent === 0) {
+ if (thresholdVertical > 0 || thresholdHorizontal > 0) {
+ percent = (getVisiblitySize(elementLeft - thresholdHorizontal, elementWidth + 2 * thresholdHorizontal, windowWidth) * getVisiblitySize(elementTop - thresholdVertical, elementHeight + 2 * thresholdVertical, windowHeight)) / ((elementWidth + 2 * thresholdHorizontal) * (elementHeight + 2 * thresholdVertical));
+ }
+ }
+ return percent;
+ }
+
+ var evalScripts = function (scripts, startIndex) {
+ var scriptsCount = scripts.length;
+ for (var i = startIndex; i < scriptsCount; i++) {
+ var breakAfterThisScript = false;
+ var script = scripts[i];
+ var newScript = document.createElement('script');
+ var type = script.getAttribute('type');
+ if (type !== null) {
+ newScript.setAttribute("type", type);
+ }
+ var src = script.getAttribute('src');
+ if (src !== null) {
+ newScript.setAttribute("src", src);
+ if ((typeof script.async === 'undefined' || script.async === false) && i + 1 < scriptsCount) {
+ breakAfterThisScript = true;
+ newScript.addEventListener('load', function () {
+ evalScripts(scripts, i + 1);
+ });
+ }
+ }
+ newScript.innerHTML = script.innerHTML;
+ script.parentNode.insertBefore(newScript, script);
+ script.parentNode.removeChild(script);
+ if (breakAfterThisScript) {
+ break;
+ }
+ }
+ };
+
+ var loadImageQueue = [];
+
+ var processLoadImageQueueLock = false;
+ var processLoadImageQueue = function () {
+ if (processLoadImageQueueLock) {
+ return;
+ }
+ processLoadImageQueueLock = true;
+ var maxSimultaneousImages = 5;
+ loadImageQueue = loadImageQueue.filter(function (item) { return item[2] !== 2 }); // Remove completed
+ for (var i = 0; i < loadImageQueue.length; i++) { // Update visibility priority
+ loadImageQueue[i][4] = getVisibilityPriority(loadImageQueue[i][1]);
+ }
+ loadImageQueue.sort(function (item1, item2) { // Sort by visibility priority
+ return item2[4] - item1[4];
+ });
+ var currentlyLoadingCount = loadImageQueue.filter(function (item) { return item[3] === 1 }).length;
+ for (var i = 0; i < loadImageQueue.length; i++) {
+ if (currentlyLoadingCount >= maxSimultaneousImages) {
+ break;
+ }
+ var item = loadImageQueue[i];
+ if (item[3] === 0) {
+ item[3] = 1; // Status: loading
+ item[2](); // Call load()
+ currentlyLoadingCount++;
+ }
+ }
+ processLoadImageQueueLock = false;
+ };
+
+ var loadImageCounter = 0;
+
+ var loadImage = function (contextElement, url, callback) {
+ loadImageCounter++;
+ var key = 'i' + loadImageCounter;
+ var timeout = null;
+ var onDone = function () {
+ clearTimeout(timeout);
+ for (var i = 0; i < loadImageQueue.length; i++) {
+ var item = loadImageQueue[i];
+ if (item[0] === key) {
+ item[3] = 2; // Status: completed
+ break;
+ }
+ }
+ processLoadImageQueue();
+ };
+ var image = new Image();
+ image.onload = function () {
+ onDone();
+ callback(true);
+ };
+ image.onerror = function () {
+ onDone();
+ callback(false);
+ };
+ var load = function () {
+ image.src = url;
+ timeout = setTimeout(onDone, 60000);
+ };
+ loadImageQueue.push([key, contextElement, load, 0, 0]); // key, element, on load function, status, visiblity priority
+ processLoadImageQueue();
+ };
+
+ var updateImage = function (type, element) {
+ var options = [];
+ var value = element.getAttribute('data-responsively-lazy');
+ var maxOptionWidth = null;
+ if (value !== null) {
+ value = value.trim();
+ if (value.length > 0) {
+ value = value.split(',');
+ for (var j = 0; j < value.length; j++) {
+ var optionImage = null;
+ var optionWidth = 999998;
+ var skipOption = false;
+ var optionParts = value[j].trim().split(' ');
+ for (var k = 0; k < optionParts.length; k++) {
+ var optionPart = optionParts[k];
+ var optionPartLength = optionPart.length;
+ if (optionPartLength === 0) {
+ continue;
+ }
+ if (optionImage === null) {
+ optionImage = optionPart;
+ } else {
+ if (optionPart[optionPartLength - 1] === 'w') {
+ optionWidth = parseInt(optionPart.substr(0, optionPartLength - 1), 10);
+ } else if (optionPart === 'webp' && !hasWebPSupport) {
+ skipOption = true;
+ } else if (optionPart === 'avif' && !hasAVIFSupport) {
+ skipOption = true;
+ }
+ }
+ }
+ if (skipOption) {
+ continue;
+ }
+ options.push([optionImage, optionWidth]);
+ if (maxOptionWidth < optionWidth) {
+ maxOptionWidth = optionWidth;
+ }
+ }
+ options.sort(function (a, b) {
+ return a[1] - b[1];
+ });
+ var temp = [];
+ for (var j = 0; j < options.length; j++) {
+ var option = options[j];
+ if (j > 0) {
+ if (option[1] === temp[temp.length - 1][1]) {
+ continue;
+ }
+ }
+ temp.push([option[0], option[1]]);
+ }
+ options = temp;
+ }
+ }
+ var preferredOption = element.getAttribute('data-responsively-lazy-preferred-option');
+ var elementWidth = preferredOption !== null ? parseInt(preferredOption) : element.offsetWidth * (typeof window.devicePixelRatio !== 'undefined' ? window.devicePixelRatio : 1);
+
+ var bestSelectedOption = null;
+ for (var j = 0; j < options.length; j++) {
+ var option = options[j];
+ if (option[1] >= elementWidth || option[1] === maxOptionWidth) { // Show the largest available option even if the element width is larger (can be webp or avif)
+ bestSelectedOption = option;
+ break;
+ }
+ }
+
+ if (bestSelectedOption === null) {
+ if (type === 'img') {
+ bestSelectedOption = [element.getAttribute('src'), 999999]; // No options found
+ } else { // background
+ bestSelectedOption = [null, 999999];
+ }
+ }
+
+ if (typeof element.responsivelyLazyOption === 'undefined') {
+ element.responsivelyLazyOption = ['', 0];
+ }
+
+ if (element.responsivelyLazyOption[1] < bestSelectedOption[1]) {
+ element.responsivelyLazyOption = bestSelectedOption;
+ var url = bestSelectedOption[0];
+ if (url === null) {
+ return;
+ }
+
+ loadImage(element, url, function (result) {
+ if (result && element.responsivelyLazyOption[0] === url) {
+ if (type === 'img') {
+ if (url === element.getAttribute('src')) {
+ element.removeAttribute('srcset');
+ } else {
+ element.setAttribute('srcset', url);
+ }
+ } else { // background
+ element.style.backgroundImage = 'url(' + url + ')';
+ }
+ if (typeof element.responsivelyLazyLoadDispached === 'undefined') {
+ element.responsivelyLazyLoadDispached = true;
+ var handler = element.getAttribute('data-on-responsively-lazy-load');
+ if (handler !== null) {
+ (new Function(handler).bind(element))();
+ }
+ if (typeof Event !== 'undefined') {
+ var event = new Event('responsively-lazy-load');
+ element.dispatchEvent(event);
+ }
+ }
+ } else {
+ element.responsivelyLazyOption = ['', 0];
+ }
+ });
+ }
+ };
+
+ var updateWindowSize = function () {
+ windowWidth = window.innerWidth;
+ windowHeight = window.innerHeight;
+ };
+
+ var updateElement = function (element) {
+
+ if (typeof element.responsivelyLazyDone !== 'undefined') {
+ return;
+ }
+
+ if (getVisibilityPriority(element) === 0) {
+ return;
+ }
+
+ var type = element.getAttribute('data-responsively-lazy-type');
+ if (type !== 'background' && type !== 'html') {
+ type = 'img';
+ }
+
+ if (type === 'html') {
+ element.responsivelyLazyDone = true;
+ mutationObserverIsDisabled = true;
+ element.innerHTML = element.getAttribute('data-responsively-lazy');
+ var scripts = element.querySelectorAll('script');
+ if (scripts.length > 0) {
+ evalScripts(scripts, 0);
+ }
+ mutationObserverIsDisabled = false;
+ } else if (type === 'img') {
+ if (hasSrcSetSupport) {
+ updateImage(type, element);
+ }
+ } else { // background
+ updateImage(type, element);
+ }
+
+ };
+
+ var run = function (element) {
+ if (hasWebPSupport === null) {
+ return;
+ }
+ if (hasAVIFSupport === null) {
+ return;
+ }
+ if (debug) {
+ var timerLabel = 'responsivelyLazy::run';
+ console.time(timerLabel);
+ }
+ if (typeof element !== 'undefined') {
+ updateElement(elements[i]);
+ } else {
+ var elements = document.querySelectorAll('[data-responsively-lazy]');
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ updateElement(elements[i]);
+ }
+ }
+ if (debug) {
+ console.timeEnd(timerLabel);
+ }
+ };
+
+ var testImageSupport = function (base64, callback) {
+ var image = new Image();
+ image.onload = image.onerror = function () {
+ callback(image);
+ };
+ image.src = 'data:image/webp;base64,' + base64;
+ };
+
+ var runIfAllTestsDone = function () {
+ if (hasWebPSupport !== null && hasAVIFSupport !== null) {
+ run();
+ }
+ };
+
+ testImageSupport('UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAD8D+JaQAA3AA/ua1AAA=', function (image) {
+ hasWebPSupport = image.width === 1;
+ runIfAllTestsDone();
+ });
+
+ testImageSupport('AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUEAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAACAAAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAEAAAABAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgSAAAAAAABNjb2xybmNseAABAA0AAIAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAAChtZGF0EgAKBzgABpAQ0AIyExAAAAAP+j9adAx6kYPdyoRe9BA=', function (image) {
+ hasAVIFSupport = image.width === 1;
+ runIfAllTestsDone();
+ });
+
+ updateWindowSize();
+
+ var requestAnimationFrameFunction = window.requestAnimationFrame || function (callback) {
+ window.setTimeout(callback, 20);
+ };
+
+ var hasChange = false;
+ var process = function () {
+ if (hasChange) {
+ hasChange = false;
+ run();
+ }
+ requestAnimationFrameFunction.call(null, process);
+ };
+ process();
+
+ if (hasIntersectionObserverSupport) {
+ var intersectionObserver = new IntersectionObserver(function (entries) {
+ for (var i in entries) {
+ var entry = entries[i];
+ if (entry.intersectionRatio > 0) {
+ updateElement(entry.target);
+ }
+ }
+ });
+ var updateIntersectionObservers = function () {
+ var elements = document.querySelectorAll('[data-responsively-lazy]');
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ if (typeof element.responsivelyLazyObserver === 'undefined') {
+ element.responsivelyLazyObserver = true;
+ intersectionObserver.observe(element);
+ }
+ }
+ };
+ var changeTimeout = null;
+ }
+
+ var setChanged = function () {
+ if (hasIntersectionObserverSupport) {
+ window.clearTimeout(changeTimeout);
+ changeTimeout = window.setTimeout(function () {
+ hasChange = true;
+ }, 50);
+ } else {
+ hasChange = true;
+ }
+ };
+
+ var updateParentNodesScrollListeners = function () {
+ var elements = document.querySelectorAll('[data-responsively-lazy]');
+ for (var i = 0; i < elements.length; i++) {
+ var parentNode = elements[i].parentNode;
+ while (parentNode && parentNode.tagName.toLowerCase() !== 'html') {
+ if (typeof parentNode.responsivelyLazyScroll === 'undefined') {
+ parentNode.responsivelyLazyScroll = true;
+ parentNode.addEventListener('scroll', setChanged);
+ }
+ parentNode = parentNode.parentNode;
+ }
+ }
+ };
+
+ var initialized = false;
+ var initialize = function () {
+ if (initialized) {
+ return;
+ }
+ initialized = true;
+ window.addEventListener('resize', function () {
+ updateWindowSize();
+ setChanged();
+ });
+ window.addEventListener('scroll', setChanged);
+ window.addEventListener('load', setChanged);
+ window.addEventListener('orientationchange', function () {
+ updateWindowSize();
+ setChanged();
+ });
+ if (hasIntersectionObserverSupport) {
+ updateIntersectionObservers();
+ }
+ updateParentNodesScrollListeners();
+ if (typeof MutationObserver !== 'undefined') {
+ var observer = new MutationObserver(function () {
+ if (!mutationObserverIsDisabled) {
+ if (hasIntersectionObserverSupport) {
+ updateIntersectionObservers();
+ }
+ updateParentNodesScrollListeners();
+ setChanged();
+ }
+ });
+ observer.observe(document.querySelector('body'), { childList: true, subtree: true });
+ }
+ };
+ document.addEventListener('readystatechange', () => { // interactive or complete
+ initialize();
+ run();
+ });
+ if (document.readyState === 'complete') {
+ initialize();
+ run();
+ }
+ } else {
+ var run = function () { };
+ }
+
+ return {
+ 'run': run
+ };
+
+}());
diff --git a/responsively-lazy.min.js b/responsively-lazy.min.js
new file mode 100644
index 0000000..699d18b
--- /dev/null
+++ b/responsively-lazy.min.js
@@ -0,0 +1,7 @@
+/*
+ * Responsively Lazy
+ * https://ivopetkov.com/responsively-lazy/
+ * Copyright (c) Ivo Petkov
+ * Free to use under the MIT license.
+*/
+var responsivelyLazy=void 0!==responsivelyLazy?responsivelyLazy:function(){if(void 0!==window.addEventListener&&void 0!==document.querySelectorAll){var e=-1!==document.cookie.indexOf("ivopetkov-responsively-lazy=debug"),n=null,t=null,A="srcset"in document.createElement("img"),r=null,i=null,o="undefined"!=typeof IntersectionObserver,l=!1,a=function(e){var n=0,t=0,A=e.getAttribute("data-responsively-lazy-threshold");if(null!==A)if("px"===A.substr(-2))n=t=parseInt(A.substr(0,A.length-2),10);else if("%"===A.substr(-1)){var o=parseInt(A.substr(0,A.length-1),10)/100;n=Math.floor(r*o),t=Math.floor(i*o)}var l=e.getBoundingClientRect(),a=l.top,s=l.left,u=l.width,d=l.height,v=function(e,n,t){return e0?Math.min(t,e+n)-Math.max(0,e):0};return 0===(o=v(s,u,r)*v(a,d,i)/(u*d)*100)&&(t>0||n>0)&&(o=v(s-n,u+2*n,r)*v(a-t,d+2*t,i)/((u+2*n)*(d+2*t))),o},s=function(e,n){for(var t=e.length,A=n;A=5);e++){var t=u[e];0===t[3]&&(t[3]=1,t[2](),n++)}d=!1}},c=0,f=function(e,A){var r=[],i=A.getAttribute("data-responsively-lazy"),o=null;if(null!==i&&(i=i.trim()).length>0){i=i.split(",");for(var l=0;l0&&m[1]===h[h.length-1][1]||h.push([m[0],m[1]])}r=h}var b=A.getAttribute("data-responsively-lazy-preferred-option"),w=null!==b?parseInt(b):A.offsetWidth*(void 0!==window.devicePixelRatio?window.devicePixelRatio:1),L=null;for(l=0;l=w||m[1]===o){L=m;break}}if(null===L&&(L="img"===e?[A.getAttribute("src"),999999]:[null,999999]),void 0===A.responsivelyLazyOption&&(A.responsivelyLazyOption=["",0]),A.responsivelyLazyOption[1]0&&s(t,0),l=!1}else"img"===n?A&&f(n,e):f(n,e)}},g=function(A){if(null!==n&&null!==t){if(e){var r="responsivelyLazy::run";console.time(r)}if(void 0!==A)p(i[o]);else for(var i=document.querySelectorAll("[data-responsively-lazy]"),o=0;o0&&p(t.target)}})),B=function(){for(var e=document.querySelectorAll("[data-responsively-lazy]"),n=0;n{k(),g()}),"complete"===document.readyState&&(k(),g())}else g=function(){};return{run:g}}();
\ No newline at end of file
diff --git a/responsivelyLazy.css b/responsivelyLazy.css
deleted file mode 100644
index cab0fcf..0000000
--- a/responsivelyLazy.css
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Responsively Lazy
- * http://ivopetkov.com/b/lazy-load-responsive-images/
- * Copyright 2015-2017, Ivo Petkov
- * Free to use under the MIT license.
-*/
-
-.responsively-lazy:not(img){
- position:relative;
- height:0;
-}
-
-.responsively-lazy:not(img) > img{
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
-}
-
-img.responsively-lazy{
- width:100%;
-}
\ No newline at end of file
diff --git a/responsivelyLazy.js b/responsivelyLazy.js
deleted file mode 100644
index 0f452e7..0000000
--- a/responsivelyLazy.js
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Responsively Lazy
- * http://ivopetkov.com/b/lazy-load-responsive-images/
- * Copyright 2015-2017, Ivo Petkov
- * Free to use under the MIT license.
- */
-
-var responsivelyLazy = typeof responsivelyLazy !== 'undefined' ? responsivelyLazy : (function () {
-
- var hasWebPSupport = false;
- var hasSrcSetSupport = false;
- var windowWidth = null;
- var windowHeight = null;
- var hasIntersectionObserverSupport = typeof IntersectionObserver !== 'undefined';
- var mutationObserverIsDisabled = false;
- var doneElements = []; // elements that should never be updated again
-
- var isVisible = function (element) {
- if (windowWidth === null) {
- return false;
- }
- var rect = element.getBoundingClientRect();
- var elementTop = rect.top;
- var elementLeft = rect.left;
- var elementWidth = rect.width;
- var elementHeight = rect.height;
- return elementTop < windowHeight && elementTop + elementHeight > 0 && elementLeft < windowWidth && elementLeft + elementWidth > 0;
- };
-
- var evalScripts = function (scripts, startIndex) {
- var scriptsCount = scripts.length;
- for (var i = startIndex; i < scriptsCount; i++) {
- var breakAfterThisScript = false;
- var script = scripts[i];
- var newScript = document.createElement('script');
- var type = script.getAttribute('type');
- if (type !== null) {
- newScript.setAttribute("type", type);
- }
- var src = script.getAttribute('src');
- if (src !== null) {
- newScript.setAttribute("src", src);
- if ((typeof script.async === 'undefined' || script.async === false) && i + 1 < scriptsCount) {
- breakAfterThisScript = true;
- newScript.addEventListener('load', function () {
- evalScripts(scripts, i + 1);
- });
- }
- }
- newScript.innerHTML = script.innerHTML;
- script.parentNode.insertBefore(newScript, script);
- script.parentNode.removeChild(script);
- if (breakAfterThisScript) {
- break;
- }
- }
- };
-
- var updateImage = function (container, element) {
- var options = element.getAttribute('data-srcset');
- if (options !== null) {
- options = options.trim();
- if (options.length > 0) {
- options = options.split(',');
- var temp = [];
- var optionsCount = options.length;
- for (var j = 0; j < optionsCount; j++) {
- var option = options[j].trim();
- if (option.length === 0) {
- continue;
- }
- var spaceIndex = option.lastIndexOf(' ');
- if (spaceIndex === -1) {
- var optionImage = option;
- var optionWidth = 999998;
- } else {
- var optionImage = option.substr(0, spaceIndex);
- var optionWidth = parseInt(option.substr(spaceIndex + 1, option.length - spaceIndex - 2), 10);
- }
- var add = false;
- if (optionImage.indexOf('.webp', optionImage.length - 5) !== -1) {
- if (hasWebPSupport) {
- add = true;
- }
- } else {
- add = true;
- }
- if (add) {
- temp.push([optionImage, optionWidth]);
- }
- }
- temp.sort(function (a, b) {
- if (a[1] < b[1]) {
- return -1;
- }
- if (a[1] > b[1]) {
- return 1;
- }
- if (a[1] === b[1]) {
- if (b[0].indexOf('.webp', b[0].length - 5) !== -1) {
- return 1;
- }
- if (a[0].indexOf('.webp', a[0].length - 5) !== -1) {
- return -1;
- }
- }
- return 0;
- });
- options = temp;
- } else {
- options = [];
- }
- } else {
- options = [];
- }
- var containerWidth = container.offsetWidth * (typeof window.devicePixelRatio !== 'undefined' ? window.devicePixelRatio : 1);
-
- var bestSelectedOption = null;
- var optionsCount = options.length;
- for (var j = 0; j < optionsCount; j++) {
- var optionData = options[j];
- if (optionData[1] >= containerWidth) {
- bestSelectedOption = optionData;
- break;
- }
- }
-
- if (bestSelectedOption === null) {
- bestSelectedOption = [element.getAttribute('src'), 999999];
- }
-
- if (typeof container.responsivelyLazyLastSetOption === 'undefined') {
- container.responsivelyLazyLastSetOption = ['', 0];
- }
- if (container.responsivelyLazyLastSetOption[1] < bestSelectedOption[1]) {
- container.responsivelyLazyLastSetOption = bestSelectedOption;
- var url = bestSelectedOption[0];
- if (typeof container.responsivelyLazyEventsAttached === 'undefined') {
- container.responsivelyLazyEventsAttached = true;
- element.addEventListener('load', function () {
- var handler = container.getAttribute('data-onlazyload');
- if (handler !== null) {
- (new Function(handler).bind(container))();
- }
- }, false);
- element.addEventListener('error', function () {
- container.responsivelyLazyLastSetOption = ['', 0];
- }, false);
- }
- if (url === element.getAttribute('src')) {
- element.removeAttribute('srcset');
- } else {
- element.setAttribute('srcset', url);
- }
- }
- };
-
- var updateWindowSize = function () {
- windowWidth = window.innerWidth;
- windowHeight = window.innerHeight;
- };
-
- var updateElement = function (element) {
-
- if (doneElements.indexOf(element) !== -1) {
- return;
- }
-
- if (!isVisible(element)) {
- return;
- }
-
- var lazyContent = element.getAttribute('data-lazycontent');
- if (lazyContent !== null) {
- doneElements.push(element);
- mutationObserverIsDisabled = true;
- element.innerHTML = lazyContent;
- var scripts = element.querySelectorAll('script');
- if (scripts.length > 0) {
- evalScripts(scripts, 0);
- }
- mutationObserverIsDisabled = false;
- return;
- }
-
- if (hasSrcSetSupport) {
- if (element.tagName.toLowerCase() === 'img') { // image with unknown height
- updateImage(element, element);
- return;
- }
-
- var imageElement = element.querySelector('img');
- if (imageElement !== null) { // image with parent container
- updateImage(element, imageElement);
- return;
- }
- }
-
- };
-
- var run = function () {
- var elements = document.querySelectorAll('.responsively-lazy');
- var elementsCount = elements.length;
- for (var i = 0; i < elementsCount; i++) {
- updateElement(elements[i]);
- }
- };
-
- if (typeof window.addEventListener !== 'undefined' && typeof document.querySelectorAll !== 'undefined') {
-
- updateWindowSize();
-
- var image = new Image();
- image.src = 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoCAAEADMDOJaQAA3AA/uuuAAA=';
- image.onload = image.onerror = function () {
- hasWebPSupport = image.width === 2;
- hasSrcSetSupport = 'srcset' in document.createElement('img');
-
- var requestAnimationFrameFunction = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) {
- window.setTimeout(callback, 1000 / 60);
- };
-
- var hasChange = true;
- var runIfHasChange = function () {
- if (hasChange) {
- hasChange = false;
- run();
- }
- requestAnimationFrameFunction.call(null, runIfHasChange);
- };
-
- runIfHasChange();
-
- if (hasIntersectionObserverSupport) {
-
- var updateIntersectionObservers = function () {
- var elements = document.querySelectorAll('.responsively-lazy');
- var elementsCount = elements.length;
- for (var i = 0; i < elementsCount; i++) {
- var element = elements[i];
- if (typeof element.responsivelyLazyObserverAttached === 'undefined') {
- element.responsivelyLazyObserverAttached = true;
- intersectionObserver.observe(element);
- }
- }
- };
-
- var intersectionObserver = new IntersectionObserver(function (entries) {
- for (var i in entries) {
- var entry = entries[i];
- if (entry.intersectionRatio > 0) {
- updateElement(entry.target);
- }
- }
- });
-
- var changeTimeout = null;
-
- }
-
- var setChanged = function () {
- if (hasIntersectionObserverSupport) {
- window.clearTimeout(changeTimeout);
- changeTimeout = window.setTimeout(function () {
- hasChange = true;
- }, 300);
- } else {
- hasChange = true;
- }
- };
-
- var updateParentNodesScrollListeners = function () {
- var elements = document.querySelectorAll('.responsively-lazy');
- var elementsCount = elements.length;
- for (var i = 0; i < elementsCount; i++) {
- var parentNode = elements[i].parentNode;
- while (parentNode && parentNode.tagName.toLowerCase() !== 'html') {
- if (typeof parentNode.responsivelyLazyScrollAttached === 'undefined') {
- parentNode.responsivelyLazyScrollAttached = true;
- parentNode.addEventListener('scroll', setChanged);
- }
- parentNode = parentNode.parentNode;
- }
- }
- };
-
- var initialize = function () {
- window.addEventListener('resize', function () {
- updateWindowSize();
- setChanged();
- });
- window.addEventListener('scroll', setChanged);
- window.addEventListener('load', setChanged);
- if (hasIntersectionObserverSupport) {
- updateIntersectionObservers();
- }
- updateParentNodesScrollListeners();
- if (typeof MutationObserver !== 'undefined') {
- var observer = new MutationObserver(function () {
- if (!mutationObserverIsDisabled) {
- if (hasIntersectionObserverSupport) {
- updateIntersectionObservers();
- }
- updateParentNodesScrollListeners();
- setChanged();
- }
- });
- observer.observe(document.querySelector('body'), { childList: true, subtree: true });
- }
- };
- if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', initialize);
- } else {
- initialize();
- }
- };
- }
-
- return {
- 'run': run,
- 'isVisible': isVisible
- };
-
-}());
diff --git a/responsivelyLazy.min.css b/responsivelyLazy.min.css
deleted file mode 100644
index 9040e8f..0000000
--- a/responsivelyLazy.min.css
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * Responsively Lazy
- * http://ivopetkov.com/b/lazy-load-responsive-images/
- * Copyright 2015-2017, Ivo Petkov
- * Free to use under the MIT license.
-*/
-.responsively-lazy:not(img){position:relative;height:0}.responsively-lazy:not(img)>img{position:absolute;top:0;left:0;width:100%;height:100%}img.responsively-lazy{width:100%;}
\ No newline at end of file
diff --git a/responsivelyLazy.min.js b/responsivelyLazy.min.js
deleted file mode 100644
index 494b283..0000000
--- a/responsivelyLazy.min.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Responsively Lazy
- * http://ivopetkov.com/b/lazy-load-responsive-images/
- * Copyright 2015-2017, Ivo Petkov
- * Free to use under the MIT license.
-*/
-var responsivelyLazy="undefined"!==typeof responsivelyLazy?responsivelyLazy:function(){var r=!1,t=!1,l=null,p=null,m="undefined"!==typeof IntersectionObserver,q=!1,u=[],v=function(a){if(null===l)return!1;var b=a.getBoundingClientRect();a=b.top;var c=b.left,d=b.width,b=b.height;return ab[1])return 1;if(a[1]===b[1]){if(-1!==b[0].indexOf(".webp",b[0].length-5))return 1;if(-1!==a[0].indexOf(".webp",a[0].length-5))return-1}return 0});c=d}else c=[];else c=[];k=a.offsetWidth*("undefined"!==typeof window.devicePixelRatio?window.devicePixelRatio:1);d=null;h=c.length;for(f=0;f=k){d=e;break}null===d&&(d=[b.getAttribute("src"),
-999999]);"undefined"===typeof a.responsivelyLazyLastSetOption&&(a.responsivelyLazyLastSetOption=["",0]);a.responsivelyLazyLastSetOption[1]