在网页上加载一张图片往往需要很长的时间,这是影响用户体验的一个较大的因素。
我们可以将通过使用一些图片懒加载的技巧,来提高用户体验,增加网站的访问量。
就此,让我们开始了解什么是懒加载,并投入学习!
懒加载是Web和应用程序开发中的一组技术,可将页面上的资源加载推迟到以后需要这些资源时,而不是先加载它们。这些技术有助于提高性能,更好地利用设备资源并降低相关成本
这种技术旨在通过按需加载图片来提升网页的加载时间。
懒加载意味着,如果我们不主动地下滑查看位于页面底部的图片,这些图片是不会被加载的。
这种懒加载的技巧适用于页面上的任何资源(特指异步和耗时的资源)
在这篇教程中,我将给通过 Javascript 你展示一些图片懒加载的技巧。
技巧一:使用JavaScript的事件
1. 创建 HTML
- 创建
<img>
。这个标签有 src 属性,用于加载图片。如果 src 被赋值, 将会根据相应地址加载图片。
<body>
<img src="https://images.unsplash.com/photo-1482784160316-6eb046863ece?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
</body>
- 为了阻止图片的加载,我们将图片的地址赋值给
<img>
中的 data-src 属性(data-src 并非<img>
的标准属性,可随意指定)。
<body>
<img class="lazy" data-src="https://images.unsplash.com/photo-1545105511-839f4a45a030?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" />
</body>
2. 添加 CSS
- 设置图片的宽(width)、高(height)、外边距(margin)
- 将 display 设置为 block,以便使图像成为块级元素。在其上下有一些空白区。
<style>
img {
width: 500px;
height: 350px;
display: block;
margin: 10px auto;
}
</style>
准备工作已经完成。是时候告诉浏览器何时加载图片了。
我们需要三个事件:scroll, resize, orientationChange ,它们都同样的重要。scroll 事件会在页面展示时与元素滑动时执行。resize 会在窗口的大小改变时执行。orientationChange 会在设备的方向改变执行。这三个事件会监控屏幕和指定懒加载的图片,并触发图片的加载。
如果上述三个事件中的任何一个执行的话,我们将找到页面上所有指定懒加载的图片。通过图像的顶部偏移量、文档的顶部位置和窗口的高度来计算其中的哪些图片在视口(viewpoint)内。如果图片进入视口,我们将<img>
中的 data-src 属性的值赋给 <img>
的 src 属性,当 <img>
的 src 属性被赋值,<img>
便会开始加载图片。
我们将指定懒加载的图片的 class 命名为 “lazy-load”,以便通过其找到这些图片。当图片加载之后,“lazy-load”和事件监听器都会被删除。
下面是示例的最终结果:
示例
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
img {
width: 500px;
height: 350px;
display: block;
margin: 10px auto;
}
</style>
</head>
<body>
<img src="https://images.unsplash.com/photo-1482784160316-6eb046863ece?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
<img src="https://images.unsplash.com/photo-1488441770602-aed21fc49bd5?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
<img src="https://images.unsplash.com/photo-1426604966848-d7adac402bff?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjExMDk0fQ&auto=format&fit=crop&w=1050&q=80" />
<img class="lazy-load" data-src="https://images.unsplash.com/photo-1545105511-839f4a45a030?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" />
<img class="lazy-load" data-src="https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
<img class="lazy-load" data-src="https://images.unsplash.com/photo-1473800447596-01729482b8eb?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
<img class="lazy-load" data-src="https://images.unsplash.com/photo-1491250974528-9443b2902f18?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
<img class="lazy-load" data-src="https://images.unsplash.com/photo-1473800447596-01729482b8eb?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
<img class="lazy-load" data-src="https://images.unsplash.com/photo-1500993855538-c6a99f437aa7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" />
<img class="lazy-load" data-src="https://images.unsplash.com/photo-1501018313157-78d10f597133?ixlib=rb-1.2.1&auto=format&fit=crop&w=1055&q=80" />
<script>
document.addEventListener("DOMContentLoaded", function() {
var lazyloadImages = document.querySelectorAll("img.lazy-load");
var lazyloadThrottleTimeout;
function lazyload () {
if(lazyloadThrottleTimeout) {
clearTimeout(lazyloadThrottleTimeout);
}
lazyloadThrottleTimeout = setTimeout(function() {
var scrollTop = window.pageYOffset;
lazyloadImages.forEach(function(img) {
if(img.offsetTop < (window.innerHeight + scrollTop)) {
img.src = img.dataset.src;
img.classList.remove('lazy');
}
});
if(lazyloadImages.length == 0) {
document.removeEventListener("scroll", lazyload);
window.removeEventListener("resize", lazyload);
window.removeEventListener("orientationChange", lazyload);
}
}, 20);
}
document.addEventListener("scroll", lazyload);
window.addEventListener("resize", lazyload);
window.addEventListener("orientationChange", lazyload);
});
</script>
</body>
</html>
技巧二: 使用 Intersection Observer API
Intersection Observer API 提供了一种异步方法,这种方法会自动"观察"元素是否可见。即目标元素是否与其祖先元素(或者顶级元素)的视口产生一个交叉区。这个 API 的使用避免了数学运算,并获得与前一种方法相同的结果。
通过 isIntersecting 属性的为真判断,我们将<img>
中的 data-src 属性的值赋给 <img>
的 src 属性,当 <img>
的 src 属性被赋值,<img>
便会开始加载图片。之后,我们会将 class 的值 “lazy-load” 和 observer 从<img>
中删除。
Intersection Observer API 并不是所有的浏览器都支持
Intersection Observer API 的使用示例如下:
示例
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
img {
width: 500px;
height: 350px;
display: block;
margin: 10px auto;
}
</style>
</head>
<body>
<img src="https://images.unsplash.com/photo-1482784160316-6eb046863ece?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
<img src="https://images.unsplash.com/photo-1488441770602-aed21fc49bd5?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
<img src="https://images.unsplash.com/photo-1426604966848-d7adac402bff?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjExMDk0fQ&auto=format&fit=crop&w=1050&q=80" />
<img class="lazy-load" data-src="https://images.unsplash.com/photo-1545105511-839f4a45a030?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" />
<img class="lazy-load" data-src="https://images.unsplash.com/photo-1493246507139-91e8fad9978e?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
<img class="lazy-load" data-src="https://images.unsplash.com/photo-1473800447596-01729482b8eb?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
<img class="lazy-load" data-src="https://images.unsplash.com/photo-1491250974528-9443b2902f18?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
<img class="lazy-load" data-src="https://images.unsplash.com/photo-1473800447596-01729482b8eb?ixlib=rb-1.2.1&auto=format&fit=crop&w=1050&q=80" />
<img class="lazy-load" data-src="https://images.unsplash.com/photo-1500993855538-c6a99f437aa7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" />
<img class="lazy-load" data-src="https://images.unsplash.com/photo-1501018313157-78d10f597133?ixlib=rb-1.2.1&auto=format&fit=crop&w=1055&q=80" />
<script>
document.addEventListener("DOMContentLoaded", function() {
var lazyloadImages;
if ("IntersectionObserver" in window) {
lazyloadImages = document.querySelectorAll(".lazy-load");
var imageObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
var image = entry.target;
image.src = image.dataset.src;
image.classList.remove("lazy-load");
imageObserver.unobserve(image);
}
});
});
lazyloadImages.forEach(function(image) {
imageObserver.observe(image);
});
} else {
var lazyloadThrottleTimeout;
lazyloadImages = document.querySelectorAll(".lazy-load");
function lazyload () {
if(lazyloadThrottleTimeout) {
clearTimeout(lazyloadThrottleTimeout);
}
lazyloadThrottleTimeout = setTimeout(function() {
var scrollTop = window.pageYOffset;
lazyloadImages.forEach(function(img) {
if(img.offsetTop < (window.innerHeight + scrollTop)) {
img.src = img.dataset.src;
img.classList.remove('lazy-load');
}
});
if(lazyloadImages.length == 0) {
document.removeEventListener("scroll", lazyload);
window.removeEventListener("resize", lazyload);
window.removeEventListener("orientationChange", lazyload);
}
}, 20);
}
document.addEventListener("scroll", lazyload);
window.addEventListener("resize", lazyload);
window.addEventListener("orientationChange", lazyload);
}
})
</script>
</body>
</html>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。