图片懒加载
懒加载:页面渲染时不加载不在页面窗口内的资源,防止页面一次性向服务器响应大量请求导致服务器响应慢,页面卡顿或崩溃。优点:页面加载速度快、可以减轻服务器的压力、节约了流量,
图片懒加载思路
- 获得需要使用懒加载的DOM元素
- 计算视口高度 window.innerHeight || document.documentElement.clientHeight; //视口高度
- 懒加载函数:判断DOM元素是否在视口中,可以用ele.getBoundingClientRect().top 获得元素距离视口的高度,大于视口高度,即不加载,小于则加载
- 给window绑定滚动事件(第三步)
优化处理
- 对滚动事件进行节流处理
- 针对加载过的资源不在进行加载,做法是给每个DOM元素设置一个isReset属性,元素加载资源前是false,加载后是true,该属性也作为上面“思路中第三部的一个条件”
- 解除绑定:当所有的懒加载的元素的isReset属性的值都是true是,解除绑定
- 对于懒加载图片来说,可以先实例化一个Image(),设置src后等实例对象onload再给DOM元素设置stc,这样可以解决加载过程中图片显示空白
下面是对图片的懒加载,html中img的src的都是同一个基础资源,所以页面渲染之初对于图片资源只加载一次,真实的资源储可以存在img的自定义属性上,也可以储存在js的变量中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0 maximum-scale=1.0 user-scalable=0"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> div{ padding: 100px; border: 1px solid red } img{ width: 400px; height: 300px; } </style> </head> <body> <div><span></span><img src="C:\Users\Administrator\Desktop\white.jpg" alt="" data_src='C:\Users\Administrator\Desktop\strawberry.jpg'></div> <div><span></span><img src="C:\Users\Administrator\Desktop\white.jpg" alt="" data_src='C:\Users\Administrator\Desktop\orange.jpg'></div> <div><span></span><img src="C:\Users\Administrator\Desktop\white.jpg" alt="" data_src='C:\Users\Administrator\Desktop\grape.jpg'></div> <div><span></span><img src="C:\Users\Administrator\Desktop\white.jpg" alt="" data_src='C:\Users\Administrator\Desktop\banana.jpg'></div> <div><span></span><img src="C:\Users\Administrator\Desktop\white.jpg" alt="" data_src='C:\Users\Administrator\Desktop\apple.jpg'></div> </body> <script> // 区别于常见的懒加载的第地方是当img重置src后,向img添加了一个isReset属性,该属性实现两点作用: // 1如果img都有这个属性,那么不会再对这个img设置src, // 2如果所有img都有这个属性,那么window的滚动事件解除懒加载函数 var imgs = document.getElementsByTagName('img'); // 因为后续使用了数组的every,所以先转换为真实数组 var innerHeight = window.innerHeight || document.documentElement.clientHeight; //视口高度 function throttle(handler,wait){ var lastTime = 0; return function(e){ nowTmie = new Date().getTime(); if(nowTmie - lastTime > wait){ lastTime = nowTmie; handler.apply(this,arguments); } } } function lazyLoad(imgs, h){ var h = h || 0; // h是一个数值,加给视口高度, var isAllLoad = imgs.every(img => { return img.getAttribute('isReset') == 'true'; }) if(isAllLoad){ window.removeEventListener("scroll", throttleLazyLoad, false) return } for (var i = 0; i < imgs.length; i++){ var top = imgs[i].getBoundingClientRect().top; // img距离视口的高度 var isLoad = imgs[i].getAttribute("isReset") // img的重置状态 if(top < innerHeight + h && !isLoad){ imgs[i].src = imgs[i].getAttribute('data_src'); imgs[i].setAttribute('isReset', 'true'); } } } lazyLoad(imgs) var throttleLazyLoad = throttle(lazyLoad, 100).bind(this, imgs, 500); // 节流的同时为了实现解除带参数的事件函数,选择了bind方法 window.addEventListener("scroll", throttleLazyLoad, false); </script> </html>