赞
踩
举个例子来说明,当打开淘宝首页的时候,只有在浏览器窗口里的图片才会被加载,当你滚动首页向下滑的时候,进入视口内的图片才会被加载,而其它从未进入视口的图像不会也不会加载。
那么延迟加载有什么好处:
那么下面就介绍延迟加载的三种实现方式:
第一种:
首先将页面上的图片的 src 属性设为 loading.gif,而图片的真实路径则设置在 data-src 属性中,页面滚动的时候计算图片的位置与滚动的位置,当图片出现在浏览器视口内时,将图片的 src 属性设置为 data-src 的值,这样,就可以实现延迟加载。
下面是具体的实现代码:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Lazyload 1</title>
- <style>
- img {
- display: block;
- margin-bottom: 50px;
- height: 200px;
- }
- </style>
- </head>
- <body>
- <img src="images/loading.gif" data-src="images/1.png">
- <img src="images/loading.gif" data-src="images/2.png">
- <img src="images/loading.gif" data-src="images/3.png">
- <img src="images/loading.gif" data-src="images/4.png">
- <img src="images/loading.gif" data-src="images/5.png">
- <img src="images/loading.gif" data-src="images/6.png">
- <img src="images/loading.gif" data-src="images/7.png">
- <img src="images/loading.gif" data-src="images/8.png">
- <img src="images/loading.gif" data-src="images/9.png">
- <img src="images/loading.gif" data-src="images/10.png">
- <img src="images/loading.gif" data-src="images/11.png">
- <img src="images/loading.gif" data-src="images/12.png">
- <script>
- function lazyload() {
- var images = document.getElementsByTagName('img');
- var len = images.length;
- var n = 0; //存储图片加载到的位置,避免每次都从第一张图片开始遍历
- return function() {
- var seeHeight = document.documentElement.clientHeight;
- var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
- for(var i = n; i < len; i++) {
- if(images[i].offsetTop < seeHeight + scrollTop) {
- if(images[i].getAttribute('src') === 'images/loading.gif') {
- images[i].src = images[i].getAttribute('data-src');
- }
- n = n + 1;
- }
- }
- }
- }
- var loadImages = lazyload();
- loadImages(); //初始化首页的页面图片
- window.addEventListener('scroll', loadImages, false);
- </script>
- </body>
- </html>
比较 image 的 offsetTop 与 seeHeight + scrollTop 的大小,当小于时则说明图片已经出现过在视口中,这时候继续判断图片是否已经替换过,如果没有替换过,则进行替换。
实现的效果:不断滑动页面时,图片延迟加载
你可以拷贝我的代码去进行实验,但是请确保 HTML 同目录下有 images 目录并且含有 1~12.png 和 loading.gif。
需要提及的是变量 n 是用来保存已经加载的图片数量,避免每次都从第一张图片开始遍历,提升性能。上面的代码用到了 JS 闭包的知识,如果你不太熟悉的话,可以自行百度一下。
第二种:
简单说来:
下面就是经过 throttle 处理后的代码:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Lazyload 2</title>
- <style>
- img {
- display: block;
- margin-bottom: 50px;
- height: 200px;
- }
- </style>
- </head>
- <body>
- <img src="images/loading.gif" data-src="images/1.png">
- <img src="images/loading.gif" data-src="images/2.png">
- <img src="images/loading.gif" data-src="images/3.png">
- <img src="images/loading.gif" data-src="images/4.png">
- <img src="images/loading.gif" data-src="images/5.png">
- <img src="images/loading.gif" data-src="images/6.png">
- <img src="images/loading.gif" data-src="images/7.png">
- <img src="images/loading.gif" data-src="images/8.png">
- <img src="images/loading.gif" data-src="images/9.png">
- <img src="images/loading.gif" data-src="images/10.png">
- <img src="images/loading.gif" data-src="images/11.png">
- <img src="images/loading.gif" data-src="images/12.png">
- <script>
- function throttle(fn, delay, atleast) {
- var timeout = null,
- startTime = new Date();
- return function() {
- var curTime = new Date();
- clearTimeout(timeout);
- if(curTime - startTime >= atleast) {
- fn();
- startTime = curTime;
- }else {
- timeout = setTimeout(fn, delay);
- }
- }
- }
- function lazyload() {
- var images = document.getElementsByTagName('img');
- var len = images.length;
- var n = 0; //存储图片加载到的位置,避免每次都从第一张图片开始遍历
- return function() {
- var seeHeight = document.documentElement.clientHeight;
- var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
- for(var i = n; i < len; i++) {
- if(images[i].offsetTop < seeHeight + scrollTop) {
- if(images[i].getAttribute('src') === 'images/loading.gif') {
- images[i].src = images[i].getAttribute('data-src');
- }
- n = n + 1;
- }
- }
- }
- }
- var loadImages = lazyload();
- loadImages(); //初始化首页的页面图片
- window.addEventListener('scroll', throttle(loadImages, 500, 1000), false);
- </script>
- </body>
- </html>
设置了 500ms 的延迟,和 1000ms 的间隔,当超过 1000ms 未触发该函数,则立即执行该函数,不然则延迟 500ms 执行该函数。
实现效果:可以看出有一定的延迟。
参考链接: 实现图片懒加载(lazyload)第三种: 使用 IntersectionObserver API
目前有一个新的 IntersectionObserver API,可以自动"观察"元素是否可见,Chrome 51+ 已经支持。
这里不过多介绍 IntersectionObserver API 的详细使用,感兴趣可以另外阅读下面的文章:
IntersectionObserver API 使用教程
Intersection Observer API
实现代码:简洁,但是浏览器尚未全部实现。
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Lazyload 3</title>
- <style>
- img {
- display: block;
- margin-bottom: 50px;
- width: 800px;
- }
- </style>
- </head>
- <body>
- <img src="images/loading.gif" data-src="images/1.png">
- <img src="images/loading.gif" data-src="images/2.png">
- <img src="images/loading.gif" data-src="images/3.png">
- <img src="images/loading.gif" data-src="images/4.png">
- <img src="images/loading.gif" data-src="images/5.png">
- <img src="images/loading.gif" data-src="images/6.png">
- <img src="images/loading.gif" data-src="images/7.png">
- <img src="images/loading.gif" data-src="images/8.png">
- <img src="images/loading.gif" data-src="images/9.png">
- <img src="images/loading.gif" data-src="images/10.png">
- <img src="images/loading.gif" data-src="images/11.png">
- <img src="images/loading.gif" data-src="images/12.png">
- <script>
- function query(selector) {
- return Array.from(document.querySelectorAll(selector));
- }
- var io = new IntersectionObserver(function(items) {
- items.forEach(function(item) {
- var target = item.target;
- if(target.getAttribute('src') == 'images/loading.gif') {
- target.src = target.getAttribute('data-src');
- }
- })
- });
- query('img').forEach(function(item) {
- io.observe(item);
- });
- </script>
- </body>
- </html>
实现效果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。