Last active
August 4, 2020 13:54
-
-
Save TransparentLC/298463165b026217e7afd494c968d44e to your computer and use it in GitHub Desktop.
部分参考 https://github.com/tuupola/lazyload 的图片懒加载插件,添加了自动选择 AVIF 和 WebP 格式的支持,本质上是在造轮子 2333
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Document</title> | |
</head> | |
<body> | |
<script src="https://cdn.jsdelivr.net/gh/w3c/IntersectionObserver/polyfill/intersection-observer.min.js"></script> | |
<script src="lazyload.js"></script> | |
<script> | |
var el = document.createElement('div'); | |
el.style.cssText = 'display:block;max-width:480px;max-height:360px;height:360px'; | |
for (var i = 0; i < 20; i++) { | |
var e = el.cloneNode(); | |
var r = Math.random().toString(16).slice(2, 10); | |
e.setAttribute('data-src', 'https://picsum.photos/seed/' + r + '/600/600'); | |
e.setAttribute('data-webp-src', 'https://picsum.photos/seed/' + r + '/600/600.webp'); | |
document.body.appendChild(e); | |
} | |
var loading = URL.createObjectURL(new Blob([ | |
'<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" display="block" preserveAspectRatio="xMidYMid" viewBox="0 0 100 100" style="margin:auto;background:0% 0%"><circle cx="50" cy="50" r="30" fill="none" stroke="#ddd" stroke-dasharray="125 55" stroke-width="8"><animateTransform attributeName="transform" dur="1s" keyTimes="0;1" repeatCount="indefinite" type="rotate" values="0 50 50;360 50 50"/></circle></svg>' | |
], {type: 'image/svg+xml'})); | |
var lazyload = new LazyLoad(document.querySelectorAll('[data-src]'), { | |
loadingSrc: loading, | |
beforeObserve: function (e) { | |
if (e.tagName.toLowerCase() !== 'img') { | |
e.style.backgroundPosition = 'center'; | |
e.style.backgroundRepeat = 'no-repeat'; | |
} | |
}, | |
afterObserve: function (e) { | |
console.log(e); | |
}, | |
}); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function (root, factory) { | |
if (typeof exports === "object") { | |
module.exports = factory(root); | |
} else if (typeof define === "function" && define.amd) { | |
define([], factory); | |
} else { | |
root.LazyLoad = factory(root); | |
} | |
})(typeof global !== "undefined" ? global : this.window || this.global, function (root) { | |
/** | |
* @typedef {Object} LazyLoadConfig | |
* @property {Element} [root] | |
* @property {String} [rootMargin] | |
* @property {Number|Number[]} [threshold] | |
* @property {String} [loadingSrc] | |
* @property {function (Element)} [beforeObserve] | |
* @property {function (Element)} [afterObserve] | |
*/ | |
/** | |
* @param {NodeList} image | |
* @param {LazyLoadConfig} config | |
*/ | |
function LazyLoad(image, config) { | |
/** @type {IntersectionObserver} */ | |
this.observer = null; | |
this.image = [].slice.call(image); | |
for (var k in this.defaults) if (!config.hasOwnProperty(k)) config[k] = this.defaults[k]; | |
this.config = config; | |
this.init(); | |
} | |
/** | |
* @param {Element} el | |
* @param {String} src | |
*/ | |
var setSrc = function (el, src) { | |
if (el.tagName.toLowerCase() === 'img') { | |
el.src = src; | |
} else { | |
el.style.backgroundImage = 'url(' + src + ')'; | |
} | |
}; | |
var useWebp = undefined; | |
var useAvif = undefined; | |
LazyLoad.prototype = { | |
/** @type {LazyLoadConfig} */ | |
defaults: { | |
root: null, | |
rootMargin: '0px', | |
threshold: 0, | |
loadingSrc: '', | |
beforeObserve: function () {}, | |
afterObserve: function () {}, | |
}, | |
init: function () { | |
var that = this; | |
this.observer = new IntersectionObserver(function (entries) { | |
entries.forEach(function (entry) { | |
if (entry.isIntersecting) { | |
var el = entry.target; | |
that.load(el); | |
} | |
}); | |
}, this.config); | |
this.image.forEach(function (/** @type {Element} */ el) { | |
setSrc(el, that.config.loadingSrc); | |
that.config.beforeObserve(el); | |
that.observer.observe(el); | |
}); | |
}, | |
/** | |
* @param {Element} el | |
*/ | |
load: function (el) { | |
var that = this; | |
// Promise.all is a better choice... | |
if (useAvif === undefined) { | |
var imgAvif = new Image; | |
imgAvif.onload = imgAvif.onerror = function() { | |
useAvif = imgAvif.width > 0; | |
if (useWebp === undefined) { | |
var imgWebp = new Image; | |
imgWebp.onload = imgWebp.onerror = function() { | |
useWebp = imgWebp.width > 0; | |
that.load(el); | |
}; | |
imgWebp.src = 'data:image/webp;base64,UklGRjIAAABXRUJQVlA4ICYAAACyAgCdASoCAAEALmk0mk0iIiIiIgBoSygABc6zbAAA/v56QAAAAA=='; | |
return; | |
} | |
that.load(el); | |
}; | |
imgAvif.src = 'data:image/avif;base64,AAAAHGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZgAAAPJtZXRhAAAAAAAAAChoZGxyAAAAAAAAAABwaWN0AAAAAAAAAAAAAAAAbGliYXZpZgAAAAAOcGl0bQAAAAAAAQAAAB5pbG9jAAAAAEQAAAEAAQAAAAEAAAEWAAAAFAAAAChpaW5mAAAAAAABAAAAGmluZmUCAAAAAAEAAGF2MDFDb2xvcgAAAABqaXBycAAAAEtpcGNvAAAAFGlzcGUAAAAAAAAAAQAAAAEAAAAQcGl4aQAAAAADCAgIAAAADGF2MUOBTQgAAAAAE2NvbHJuY2x4AAIAAgACgAAAABdpcG1hAAAAAAAAAAEAAQQBAoMEAAAAHG1kYXQSAAoFWAAOxIAyCRAAAAAP+I9ngg=='; | |
return; | |
} | |
setSrc(el, (useAvif && el.getAttribute('data-avif-src')) || (useWebp && el.getAttribute('data-webp-src')) || el.getAttribute('data-src')); | |
this.observer.unobserve(el); | |
this.config.afterObserve(el); | |
}, | |
destroy: function () { | |
if (!this.settings) return; | |
this.observer.disconnect(); | |
this.config = null; | |
}, | |
}; | |
return LazyLoad; | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Document</title> | |
</head> | |
<body> | |
<p>Scroll down and the image will appear below.</p> | |
<p>The image will be the AV1/WebP/JPEG logo if your browser support that format. </p> | |
<div style="height:1280px"></div> | |
<hr> | |
<img | |
height="256" | |
data-src="https://bj.bcebos.com/im-cs/32316d5b7e4ff72a2e31ff364b631fcc.jpg" | |
data-webp-src="https://bj.bcebos.com/im-cs/14489017c6674588093174dea7a89e81.webp" | |
data-avif-src="https://bj.bcebos.com/im-cs/534cfa1d5d7bb418197cdf0cdc2f1332.avif" | |
> | |
<script src="https://cdn.jsdelivr.net/gh/w3c/IntersectionObserver/polyfill/intersection-observer.min.js"></script> | |
<script src="lazyload.js"></script> | |
<script> | |
var loading = URL.createObjectURL(new Blob([ | |
'<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" display="block" preserveAspectRatio="xMidYMid" viewBox="0 0 100 100" style="margin:auto;background:0% 0%"><circle cx="50" cy="50" r="30" fill="none" stroke="#ddd" stroke-dasharray="125 55" stroke-width="8"><animateTransform attributeName="transform" dur="1s" keyTimes="0;1" repeatCount="indefinite" type="rotate" values="0 50 50;360 50 50"/></circle></svg>' | |
], {type: 'image/svg+xml'})); | |
var lazyload = new LazyLoad(document.querySelectorAll('[data-src]'), { | |
loadingSrc: loading, | |
afterObserve: function (e) { | |
console.log(e); | |
}, | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment