vanilla-lazyload
Advanced tools
Comparing version 10.5.2 to 10.7.0
@@ -1,2 +0,2 @@ | ||
import {setSources, setSourcesForPicture} from "../src/lazyLoad.setSources"; | ||
import {setSources, setSourcesInChildren} from "../src/lazyLoad.setSources"; | ||
@@ -129,6 +129,5 @@ const lazyloadSettings = { | ||
describe("setSourcesForPicture", () => { | ||
let picture, source1, source2, img; | ||
describe("setSourcesInChildren", () => { | ||
let container, source1, source2, img; | ||
let img1 = "http://placehold.it/1x1"; | ||
let img100 = "http://placehold.it/100x100"; | ||
let img200 = "http://placehold.it/200x200"; | ||
@@ -138,7 +137,6 @@ let img400 = "http://placehold.it/400x400"; | ||
beforeEach(() => { | ||
// Parent is a picture | ||
picture = document.createElement("picture"); | ||
picture.appendChild(source1 = document.createElement("source")); | ||
picture.appendChild(source2 = document.createElement("source")); | ||
picture.appendChild(img = document.createElement("img")); | ||
container = document.createElement("picture"); | ||
container.appendChild(source1 = document.createElement("source")); | ||
container.appendChild(source2 = document.createElement("source")); | ||
container.appendChild(img = document.createElement("img")); | ||
}); | ||
@@ -149,3 +147,3 @@ | ||
source2.setAttribute("data-srcset", img400); | ||
setSourcesForPicture(img, lazyloadSettings); | ||
setSourcesInChildren(container, "srcset", "srcset"); | ||
expect(source1).toHaveAttributeValue("srcset", img200); | ||
@@ -160,3 +158,3 @@ expect(source2).toHaveAttributeValue("srcset", img400); | ||
source2.setAttribute("srcset", img1); | ||
setSourcesForPicture(img, lazyloadSettings); | ||
setSourcesInChildren(container, "srcset", "srcset"); | ||
expect(source1).toHaveAttributeValue("srcset", img200); | ||
@@ -171,6 +169,72 @@ expect(source2).toHaveAttributeValue("srcset", img400); | ||
source2.setAttribute("srcset", img400); | ||
setSourcesForPicture(img, lazyloadSettings); | ||
setSourcesInChildren(container, "srcset", "srcset"); | ||
expect(source1).toHaveAttributeValue("srcset", img200); | ||
expect(source2).toHaveAttributeValue("srcset", img400); | ||
}); | ||
test("...with initially empty src", () => { | ||
source1.setAttribute("data-src", img200); | ||
source2.setAttribute("data-src", img400); | ||
setSourcesInChildren(container, "src", "src"); | ||
expect(source1).toHaveAttributeValue("src", img200); | ||
expect(source2).toHaveAttributeValue("src", img400); | ||
}); | ||
test("...with initial value in src", () => { | ||
source1.setAttribute("data-src", img200); | ||
source2.setAttribute("data-src", img400); | ||
source1.setAttribute("src", img1); | ||
source2.setAttribute("src", img1); | ||
setSourcesInChildren(container, "src", "src"); | ||
expect(source1).toHaveAttributeValue("src", img200); | ||
expect(source2).toHaveAttributeValue("src", img400); | ||
}); | ||
test("...with initial value in src and empty data-src", () => { | ||
source1.setAttribute("data-src", ""); | ||
source2.setAttribute("data-src", ""); | ||
source1.setAttribute("src", img200); | ||
source2.setAttribute("src", img400); | ||
setSourcesInChildren(container, "src", "src"); | ||
expect(source1).toHaveAttributeValue("src", img200); | ||
expect(source2).toHaveAttributeValue("src", img400); | ||
}); | ||
}); | ||
describe("setSources for video", () => { | ||
let video, source1, source2; | ||
let videoUrl = "https://youtu.be/foobar"; | ||
beforeEach(() => { | ||
video = document.createElement("video"); | ||
video.appendChild(source1 = document.createElement("source")); | ||
video.appendChild(source2 = document.createElement("source")); | ||
}); | ||
test("...with initially empty src", () => { | ||
video.setAttribute("data-src", videoUrl); | ||
setSources(video, lazyloadSettings); | ||
expect(video).toHaveAttributeValue("src", videoUrl); | ||
}); | ||
}); | ||
describe("setSources for picture", () => { | ||
let picture, source1, source2, img; | ||
let img200 = "http://placehold.it/200x200"; | ||
let img400 = "http://placehold.it/400x400"; | ||
beforeEach(() => { | ||
picture = document.createElement("picture"); | ||
picture.appendChild(source1 = document.createElement("source")); | ||
picture.appendChild(source2 = document.createElement("source")); | ||
picture.appendChild(img = document.createElement("img")); | ||
}); | ||
test("...with initially empty srcset", () => { | ||
img.setAttribute("data-src", img200); | ||
img.setAttribute("data-srcset", img400); | ||
setSources(img, lazyloadSettings); | ||
expect(img).toHaveAttributeValue("src", img200); | ||
expect(img).toHaveAttributeValue("srcset", img400); | ||
}); | ||
}); |
@@ -5,2 +5,7 @@ # CHANGELOG | ||
#### 10.6.0 | ||
- Added a demo with a popup layer and images injected after popup open. Closes #196. | ||
- Updated the `background_images` demo with a custom management of the loading class and the loaded event callback. | ||
#### 10.5.2 | ||
@@ -92,2 +97,6 @@ | ||
#### 8.7.1 | ||
Added a security check on lazy elements' parents. | ||
#### 8.7.0 | ||
@@ -94,0 +103,0 @@ |
@@ -73,13 +73,8 @@ (function (global, factory) { | ||
const setSourcesForPicture = function (element, settings) { | ||
const {data_srcset: dataSrcSet} = settings; | ||
const parent = element.parentNode; | ||
if (!parent || parent.tagName !== "PICTURE") { | ||
return; | ||
} | ||
for (let i = 0, pictureChild; pictureChild = parent.children[i]; i += 1) { | ||
if (pictureChild.tagName === "SOURCE") { | ||
let sourceSrcset = getData(pictureChild, dataSrcSet); | ||
if (sourceSrcset) { | ||
pictureChild.setAttribute("srcset", sourceSrcset); | ||
const setSourcesInChildren = function(parentTag, attrName, dataAttrName) { | ||
for (let i = 0, childTag; childTag = parentTag.children[i]; i += 1) { | ||
if (childTag.tagName === "SOURCE") { | ||
let attributeValue = getData(childTag, dataAttrName); | ||
if (attributeValue) { | ||
childTag.setAttribute(attrName, attributeValue); | ||
} | ||
@@ -90,23 +85,31 @@ } | ||
const setAttributeIfNotNullOrEmpty = function(element, attrName, value) { | ||
if (!value) {return;} | ||
element.setAttribute(attrName, value); | ||
}; | ||
const setSources = function (element, settings) { | ||
const {data_src: dataSrc, data_srcset: dataSrcSet} = settings; | ||
const dataAttrSrcName = settings.data_src; | ||
const elementSrc = getData(element, dataAttrSrcName); | ||
const tagName = element.tagName; | ||
const elementSrc = getData(element, dataSrc); | ||
if (tagName === "IMG") { | ||
setSourcesForPicture(element, settings); | ||
const imgSrcset = getData(element, dataSrcSet); | ||
if (imgSrcset) { | ||
element.setAttribute("srcset", imgSrcset); | ||
const dataAttrSrcSetName = settings.data_srcset; | ||
const elementSrcSet = getData(element, dataAttrSrcSetName); | ||
const parent = element.parentNode; | ||
if (parent && parent.tagName === "PICTURE") { | ||
setSourcesInChildren(parent, "srcset", dataAttrSrcSetName); | ||
} | ||
if (elementSrc) { | ||
element.setAttribute("src", elementSrc); | ||
} | ||
setAttributeIfNotNullOrEmpty(element, "srcset", elementSrcSet); | ||
setAttributeIfNotNullOrEmpty(element, "src", elementSrc); | ||
return; | ||
} | ||
if (tagName === "IFRAME") { | ||
if (elementSrc) { | ||
element.setAttribute("src", elementSrc); | ||
} | ||
setAttributeIfNotNullOrEmpty(element, "src", elementSrc); | ||
return; | ||
} | ||
if (tagName === "VIDEO") { | ||
setSourcesInChildren(element, "src", dataAttrSrcName); | ||
setAttributeIfNotNullOrEmpty(element, "src", elementSrc); | ||
return; | ||
} | ||
if (elementSrc) { | ||
@@ -175,3 +178,3 @@ element.style.backgroundImage = `url("${elementSrc}")`; | ||
callCallback(settings.callback_enter, element); | ||
if (["IMG", "IFRAME"].indexOf(element.tagName) > -1) { | ||
if (["IMG", "IFRAME", "VIDEO"].indexOf(element.tagName) > -1) { | ||
addOneShotListeners(element, settings); | ||
@@ -178,0 +181,0 @@ addClass(element, settings.class_loading); |
@@ -75,14 +75,8 @@ var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var setSourcesForPicture = function setSourcesForPicture(element, settings) { | ||
var dataSrcSet = settings.data_srcset; | ||
var parent = element.parentNode; | ||
if (!parent || parent.tagName !== "PICTURE") { | ||
return; | ||
} | ||
for (var i = 0, pictureChild; pictureChild = parent.children[i]; i += 1) { | ||
if (pictureChild.tagName === "SOURCE") { | ||
var sourceSrcset = getData(pictureChild, dataSrcSet); | ||
if (sourceSrcset) { | ||
pictureChild.setAttribute("srcset", sourceSrcset); | ||
var setSourcesInChildren = function setSourcesInChildren(parentTag, attrName, dataAttrName) { | ||
for (var i = 0, childTag; childTag = parentTag.children[i]; i += 1) { | ||
if (childTag.tagName === "SOURCE") { | ||
var attributeValue = getData(childTag, dataAttrName); | ||
if (attributeValue) { | ||
childTag.setAttribute(attrName, attributeValue); | ||
} | ||
@@ -93,25 +87,33 @@ } | ||
var setAttributeIfNotNullOrEmpty = function setAttributeIfNotNullOrEmpty(element, attrName, value) { | ||
if (!value) { | ||
return; | ||
} | ||
element.setAttribute(attrName, value); | ||
}; | ||
var setSources = function setSources(element, settings) { | ||
var dataSrc = settings.data_src, | ||
dataSrcSet = settings.data_srcset; | ||
var dataAttrSrcName = settings.data_src; | ||
var elementSrc = getData(element, dataAttrSrcName); | ||
var tagName = element.tagName; | ||
var elementSrc = getData(element, dataSrc); | ||
if (tagName === "IMG") { | ||
setSourcesForPicture(element, settings); | ||
var imgSrcset = getData(element, dataSrcSet); | ||
if (imgSrcset) { | ||
element.setAttribute("srcset", imgSrcset); | ||
var dataAttrSrcSetName = settings.data_srcset; | ||
var elementSrcSet = getData(element, dataAttrSrcSetName); | ||
var parent = element.parentNode; | ||
if (parent && parent.tagName === "PICTURE") { | ||
setSourcesInChildren(parent, "srcset", dataAttrSrcSetName); | ||
} | ||
if (elementSrc) { | ||
element.setAttribute("src", elementSrc); | ||
} | ||
setAttributeIfNotNullOrEmpty(element, "srcset", elementSrcSet); | ||
setAttributeIfNotNullOrEmpty(element, "src", elementSrc); | ||
return; | ||
} | ||
if (tagName === "IFRAME") { | ||
if (elementSrc) { | ||
element.setAttribute("src", elementSrc); | ||
} | ||
setAttributeIfNotNullOrEmpty(element, "src", elementSrc); | ||
return; | ||
} | ||
if (tagName === "VIDEO") { | ||
setSourcesInChildren(element, "src", dataAttrSrcName); | ||
setAttributeIfNotNullOrEmpty(element, "src", elementSrc); | ||
return; | ||
} | ||
if (elementSrc) { | ||
@@ -180,3 +182,3 @@ element.style.backgroundImage = 'url("' + elementSrc + '")'; | ||
callCallback(settings.callback_enter, element); | ||
if (["IMG", "IFRAME"].indexOf(element.tagName) > -1) { | ||
if (["IMG", "IFRAME", "VIDEO"].indexOf(element.tagName) > -1) { | ||
addOneShotListeners(element, settings); | ||
@@ -183,0 +185,0 @@ addClass(element, settings.class_loading); |
@@ -1,1 +0,1 @@ | ||
var _extends=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};!function(e,t){"object"===("undefined"==typeof exports?"undefined":_typeof(exports))&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.LazyLoad=t()}(this,function(){"use strict";var e=function(e){var t={elements_selector:"img",container:document,threshold:300,data_src:"src",data_srcset:"srcset",class_loading:"loading",class_loaded:"loaded",class_error:"error",callback_load:null,callback_error:null,callback_set:null,callback_enter:null};return _extends({},t,e)},t=function(e,t){return e.getAttribute("data-"+t)},n=function(e,t,n){return e.setAttribute("data-"+t,n)},r=function(e){return e.filter(function(e){return!t(e,"was-processed")})},s=function(e,t){var n,r=new e(t);try{n=new CustomEvent("LazyLoad::Initialized",{detail:{instance:r}})}catch(e){(n=document.createEvent("CustomEvent")).initCustomEvent("LazyLoad::Initialized",!1,!1,{instance:r})}window.dispatchEvent(n)},o=function(e,n){var r=n.data_srcset,s=e.parentNode;if(s&&"PICTURE"===s.tagName)for(var o,a=0;o=s.children[a];a+=1)if("SOURCE"===o.tagName){var i=t(o,r);i&&o.setAttribute("srcset",i)}},a=function(e,n){var r=n.data_src,s=n.data_srcset,a=e.tagName,i=t(e,r);if("IMG"===a){o(e,n);var c=t(e,s);return c&&e.setAttribute("srcset",c),void(i&&e.setAttribute("src",i))}"IFRAME"!==a?i&&(e.style.backgroundImage='url("'+i+'")'):i&&e.setAttribute("src",i)},i="undefined"!=typeof window,c=i&&"IntersectionObserver"in window,l=i&&"classList"in document.createElement("p"),u=function(e,t){l?e.classList.add(t):e.className+=(e.className?" ":"")+t},d=function(e,t){l?e.classList.remove(t):e.className=e.className.replace(new RegExp("(^|\\s+)"+t+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")},f=function(e,t){e&&e(t)},_=function(e,t,n){e.removeEventListener("load",t),e.removeEventListener("error",n)},v=function(e,t){var n=function n(s){m(s,!0,t),_(e,n,r)},r=function r(s){m(s,!1,t),_(e,n,r)};e.addEventListener("load",n),e.addEventListener("error",r)},m=function(e,t,n){var r=e.target;d(r,n.class_loading),u(r,t?n.class_loaded:n.class_error),f(t?n.callback_load:n.callback_error,r)},b=function(e,t){f(t.callback_enter,e),["IMG","IFRAME"].indexOf(e.tagName)>-1&&(v(e,t),u(e,t.class_loading)),a(e,t),n(e,"was-processed",!0),f(t.callback_set,e)},p=function(e){return e.isIntersecting||e.intersectionRatio>0},h=function(t,n){this._settings=e(t),this._setObserver(),this.update(n)};h.prototype={_setObserver:function(){var e=this;if(c){var t=this._settings,n={root:t.container===document?null:t.container,rootMargin:t.threshold+"px"};this._observer=new IntersectionObserver(function(t){t.forEach(function(t){if(p(t)){var n=t.target;b(n,e._settings),e._observer.unobserve(n)}}),e._elements=r(e._elements)},n)}},update:function(e){var t=this,n=this._settings,s=e||n.container.querySelectorAll(n.elements_selector);this._elements=r(Array.prototype.slice.call(s)),this._observer?this._elements.forEach(function(e){t._observer.observe(e)}):(this._elements.forEach(function(e){b(e,n)}),this._elements=r(this._elements))},destroy:function(){var e=this;this._observer&&(r(this._elements).forEach(function(t){e._observer.unobserve(t)}),this._observer=null),this._elements=null,this._settings=null}};var y=window.lazyLoadOptions;return i&&y&&function(e,t){if(t.length)for(var n,r=0;n=t[r];r+=1)s(e,n);else s(e,t)}(h,y),h}); | ||
var _extends=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};!function(e,t){"object"===("undefined"==typeof exports?"undefined":_typeof(exports))&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.LazyLoad=t()}(this,function(){"use strict";var e=function(e){var t={elements_selector:"img",container:document,threshold:300,data_src:"src",data_srcset:"srcset",class_loading:"loading",class_loaded:"loaded",class_error:"error",callback_load:null,callback_error:null,callback_set:null,callback_enter:null};return _extends({},t,e)},t=function(e,t){return e.getAttribute("data-"+t)},n=function(e,t,n){return e.setAttribute("data-"+t,n)},r=function(e){return e.filter(function(e){return!t(e,"was-processed")})},s=function(e,t){var n,r=new e(t);try{n=new CustomEvent("LazyLoad::Initialized",{detail:{instance:r}})}catch(e){(n=document.createEvent("CustomEvent")).initCustomEvent("LazyLoad::Initialized",!1,!1,{instance:r})}window.dispatchEvent(n)},o=function(e,n,r){for(var s,o=0;s=e.children[o];o+=1)if("SOURCE"===s.tagName){var a=t(s,r);a&&s.setAttribute(n,a)}},a=function(e,t,n){n&&e.setAttribute(t,n)},i=function(e,n){var r=n.data_src,s=t(e,r),i=e.tagName;if("IMG"===i){var c=n.data_srcset,l=t(e,c),u=e.parentNode;return u&&"PICTURE"===u.tagName&&o(u,"srcset",c),a(e,"srcset",l),void a(e,"src",s)}if("IFRAME"!==i)return"VIDEO"===i?(o(e,"src",r),void a(e,"src",s)):void(s&&(e.style.backgroundImage='url("'+s+'")'));a(e,"src",s)},c="undefined"!=typeof window,l=c&&"IntersectionObserver"in window,u=c&&"classList"in document.createElement("p"),d=function(e,t){u?e.classList.add(t):e.className+=(e.className?" ":"")+t},f=function(e,t){u?e.classList.remove(t):e.className=e.className.replace(new RegExp("(^|\\s+)"+t+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")},v=function(e,t){e&&e(t)},_=function(e,t,n){e.removeEventListener("load",t),e.removeEventListener("error",n)},m=function(e,t){var n=function n(s){b(s,!0,t),_(e,n,r)},r=function r(s){b(s,!1,t),_(e,n,r)};e.addEventListener("load",n),e.addEventListener("error",r)},b=function(e,t,n){var r=e.target;f(r,n.class_loading),d(r,t?n.class_loaded:n.class_error),v(t?n.callback_load:n.callback_error,r)},p=function(e,t){v(t.callback_enter,e),["IMG","IFRAME","VIDEO"].indexOf(e.tagName)>-1&&(m(e,t),d(e,t.class_loading)),i(e,t),n(e,"was-processed",!0),v(t.callback_set,e)},h=function(e){return e.isIntersecting||e.intersectionRatio>0},y=function(t,n){this._settings=e(t),this._setObserver(),this.update(n)};y.prototype={_setObserver:function(){var e=this;if(l){var t=this._settings,n={root:t.container===document?null:t.container,rootMargin:t.threshold+"px"};this._observer=new IntersectionObserver(function(t){t.forEach(function(t){if(h(t)){var n=t.target;p(n,e._settings),e._observer.unobserve(n)}}),e._elements=r(e._elements)},n)}},update:function(e){var t=this,n=this._settings,s=e||n.container.querySelectorAll(n.elements_selector);this._elements=r(Array.prototype.slice.call(s)),this._observer?this._elements.forEach(function(e){t._observer.observe(e)}):(this._elements.forEach(function(e){p(e,n)}),this._elements=r(this._elements))},destroy:function(){var e=this;this._observer&&(r(this._elements).forEach(function(t){e._observer.unobserve(t)}),this._observer=null),this._elements=null,this._settings=null}};var g=window.lazyLoadOptions;return c&&g&&function(e,t){if(t.length)for(var n,r=0;n=t[r];r+=1)s(e,n);else s(e,t)}(y,g),y}); |
{ | ||
"name": "vanilla-lazyload", | ||
"version": "10.5.2", | ||
"version": "10.7.0", | ||
"description": "A fast, lightweight script to load images as they enter the viewport. SEO friendly, it supports responsive images (both srcset + sizes and picture) and progressive JPEG", | ||
@@ -5,0 +5,0 @@ "main": "dist/lazyload.min.js", |
@@ -17,3 +17,3 @@ LazyLoad is a fast, lightweight and flexible script that _speeds up your web application_ by **loading images as they enter the viewport**. It's written in plain "vanilla" JavaScript, uses [Intersection Observers](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API), and supports [responsive images](https://alistapart.com/article/responsive-images-in-practice). It's also SEO-friendly and it has some other [notable features](#notable-features). | ||
```html | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/vanilla-lazyload/8.7.0/lazyload.min.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/vanilla-lazyload/8.7.1/lazyload.min.js"></script> | ||
``` | ||
@@ -38,3 +38,3 @@ | ||
var s = d.createElement("script"); s.async = true; | ||
var v = !("IntersectionObserver" in w) ? "8.7.0" : "10.5.2"; | ||
var v = !("IntersectionObserver" in w) ? "8.7.1" : "10.5.2"; | ||
s.src = "https://cdnjs.cloudflare.com/ajax/libs/vanilla-lazyload/" + v + "/lazyload.min.js"; | ||
@@ -55,6 +55,6 @@ w.lazyLoadOptions = {}; // Your options here. See "recipes" for more information about async. | ||
- **install it with npm** | ||
Recommended version `npm install vanilla-lazyload@8.7.0` | ||
Recommended version `npm install vanilla-lazyload@8.7.1` | ||
Latest version `npm install vanilla-lazyload` | ||
- **install it with bower** | ||
Recommended version `bower install vanilla-lazyload#8.7.0` | ||
Recommended version `bower install vanilla-lazyload#8.7.1` | ||
Latest version `bower install vanilla-lazyload` | ||
@@ -436,3 +436,3 @@ | ||
Images should be shown while they load, and not after, to give your users the best perceived performance. This is especially true if you use a progressive loading format like **progressive JPEG**. | ||
Images should be shown while they load, and not after, to give your users the best perceived performance. This is especially true if you use a progressive loading format like **Progressive JPEG**. | ||
@@ -450,4 +450,15 @@ In order to make your images visible as soon as LazyLoad sets the `src`/`srcset` attribute to it, you can either: | ||
Or do it using the **CSS classes** set by LazyLoad when loading starts - see [API](#api). | ||
Or instead of the above `:not()` selector do it using the **CSS classes** of `class_loading` and `class_loaded` set by LazyLoad when loading starts or is completed - see [API](#api). | ||
### Do NOT use placeholder images | ||
We do not recommend to use a placeholder image (like a transparent pixel GIF) in your HTML. | ||
* For **best perceived preformance, leave the `src` and `srcset` attributes blank**. Doing so, the image will be shown as soon as LazyLoad starts loading the image. See [this video](https://youtu.be/2E3ociaFJS0) or [this pen](https://codepen.io/verlok/pen/bKYggE?editors=0110) to test the difference (remember to disable the cache and to set a slower connection speed if you have a very fast one). | ||
* If you put anything in the src (like a transparent GIF), then LazyLoad starts loading the image but it won't be shown by browsers until the new image is loaded, leading to a **worse perceived performance**. | ||
It's safe not to put any value in the `src` nor `srcset` attributes, even if your HTML won't validate by a static code analyzer. The reason is that once JavaScript is executed, those values will be set by LazyLoad. For SEO, if the client is a crawler like Googlebot, it will be detected by LazyLoad which will fix the HTML. | ||
<!-- | ||
@@ -484,3 +495,3 @@ MOAR points to add to the README: | ||
| `container` | The scrolling container, and the container of the elements in the `elements_selector` option. | `document` | | ||
| `elements_selector` | The string selector of the elements to load lazily, to be selected as descendants of the `container` object. | `"img"` | | ||
| `elements_selector` | The string selector of the elements to load lazily, to be selected as descendants of the `container` object. For multiple elements, you can add the css selectors for the same followed by a comma. E.g.: `'iframe, img, .container_class'`. This will lazy load images for iframe and img elements along with the images/background images under `'container_class'` | `"img"` | | ||
| `threshold` | The distance out of the viewport, expressed in pixel, before which to start loading the images | `300` | | ||
@@ -487,0 +498,0 @@ | `data_src` | The name of the data attribute containing the original image source, excluding the `"data-"` part. E.g. if your data attribute is named `"data-src"`, just pass `"src"` | `"src"` | |
@@ -41,3 +41,3 @@ import {setSources} from "./lazyload.setSources"; | ||
callCallback(settings.callback_enter, element); | ||
if (["IMG", "IFRAME"].indexOf(element.tagName) > -1) { | ||
if (["IMG", "IFRAME", "VIDEO"].indexOf(element.tagName) > -1) { | ||
addOneShotListeners(element, settings); | ||
@@ -44,0 +44,0 @@ addClass(element, settings.class_loading); |
import {getData} from "./lazyload.data"; | ||
export const setSourcesForPicture = function (element, settings) { | ||
const {data_srcset: dataSrcSet} = settings; | ||
const parent = element.parentNode; | ||
if (!parent || parent.tagName !== "PICTURE") { | ||
return; | ||
} | ||
for (let i = 0, pictureChild; pictureChild = parent.children[i]; i += 1) { | ||
if (pictureChild.tagName === "SOURCE") { | ||
let sourceSrcset = getData(pictureChild, dataSrcSet); | ||
if (sourceSrcset) { | ||
pictureChild.setAttribute("srcset", sourceSrcset); | ||
export const setSourcesInChildren = function(parentTag, attrName, dataAttrName) { | ||
for (let i = 0, childTag; childTag = parentTag.children[i]; i += 1) { | ||
if (childTag.tagName === "SOURCE") { | ||
let attributeValue = getData(childTag, dataAttrName); | ||
if (attributeValue) { | ||
childTag.setAttribute(attrName, attributeValue); | ||
} | ||
@@ -19,23 +14,31 @@ } | ||
export const setAttributeIfNotNullOrEmpty = function(element, attrName, value) { | ||
if (!value) {return;} | ||
element.setAttribute(attrName, value); | ||
}; | ||
export const setSources = function (element, settings) { | ||
const {data_src: dataSrc, data_srcset: dataSrcSet} = settings; | ||
const dataAttrSrcName = settings.data_src; | ||
const elementSrc = getData(element, dataAttrSrcName); | ||
const tagName = element.tagName; | ||
const elementSrc = getData(element, dataSrc); | ||
if (tagName === "IMG") { | ||
setSourcesForPicture(element, settings); | ||
const imgSrcset = getData(element, dataSrcSet); | ||
if (imgSrcset) { | ||
element.setAttribute("srcset", imgSrcset); | ||
const dataAttrSrcSetName = settings.data_srcset; | ||
const elementSrcSet = getData(element, dataAttrSrcSetName); | ||
const parent = element.parentNode; | ||
if (parent && parent.tagName === "PICTURE") { | ||
setSourcesInChildren(parent, "srcset", dataAttrSrcSetName); | ||
} | ||
if (elementSrc) { | ||
element.setAttribute("src", elementSrc); | ||
} | ||
setAttributeIfNotNullOrEmpty(element, "srcset", elementSrcSet); | ||
setAttributeIfNotNullOrEmpty(element, "src", elementSrc); | ||
return; | ||
} | ||
if (tagName === "IFRAME") { | ||
if (elementSrc) { | ||
element.setAttribute("src", elementSrc); | ||
} | ||
setAttributeIfNotNullOrEmpty(element, "src", elementSrc); | ||
return; | ||
} | ||
if (tagName === "VIDEO") { | ||
setSourcesInChildren(element, "src", dataAttrSrcName); | ||
setAttributeIfNotNullOrEmpty(element, "src", elementSrc); | ||
return; | ||
} | ||
if (elementSrc) { | ||
@@ -42,0 +45,0 @@ element.style.backgroundImage = `url("${elementSrc}")`; |
Sorry, the diff of this file is not supported yet
915493
135
1066
536