原理:
将页面中的img标签src指向一张小图片或者src为空,然后定义data-src
(这个属性可以自定义命名,我自己用data-src)属性指向真实的图片。
src
指向一张默认的图片,否则当src
为空时也会向服务器发送一次请求。可以指向loading
的地址。
代码实现:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>图片懒加载</title> </head> <style> img{ width: 100%; height: 300px; } </style> <body> <div id="lazyLoad"> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt=""> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt=""> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt=""> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt=""> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt=""> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt=""> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt=""> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt=""> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt=""> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt=""> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt=""> </div> </body> <script> window.onload = function(){ function lazyLoad(){ var lazyLoadContainer = document.getElementById(‘lazyLoad‘); var imgLen = lazyLoadContainer.getElementsByTagName(‘img‘).length;//如果图片长度不是固定,而是分页请求的话,则放在return函数中 var imgList = lazyLoadContainer.getElementsByTagName(‘img‘); var screenW = document.documentElement.clientWidth; var count = 0;//统计懒加载多少图片 return function(){ console.log(count); var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;//兼容不同浏览器 for(var i = count; i<imgLen; i++){ //console.log(‘offsetTop‘, imgList[i].offsetTop); //console.log(‘scrollHeight‘, scrollTop + screenW); if(imgList[i].offsetTop < scrollTop + screenW-300){ if(imgList[i].getAttribute(‘src‘) === ‘https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg‘){ imgList[i].src = imgList[i].getAttribute(‘data-src‘); count += 1; } } } } } var useLazyLoad = lazyLoad(); useLazyLoad(); //函数节流 function throttle(action, delay, time){ var timer, startTime = new Date(); return function(){ var context = this, arg = arguments, curTime = new Date(); if(timer){ clearTimeout(timer); } if(curTime - startTime > time){ action.apply(context,arg); startTime = curTime; }else{ timer = setTimeout(function(){ action.apply(context,arg); },delay) } } } window.addEventListener(‘scroll‘, throttle(useLazyLoad,500,100)) } </script> </html>
函数节流和函数去抖
以下场景往往由于事件频繁被触发,因而频繁执行DOM操作、资源加载等重行为,导致UI停顿甚至浏览器崩溃。
- window对象的resize、scroll事件
- 拖拽时的mousemove事件
- 射击游戏中的mousedown、keydown事件
-
文字输入、自动完成的keyup事件
当调用动作n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间。这种比较适合window的resize事件(函数去抖);实际需求大多为停止改变大小n毫秒后执行后续处理;而其他事件大多的需求是以一定的频率执行后续处理(函数节流)
function debounce(action,delay){//函数去抖 var timer = null; return function(){ //console.log(‘timer‘,timer) if(timer){ clearTimeout(timer); } var context = this; arg = arguments; timer = setTimeout(function(){ action.apply(context,arg) },delay); } } function throttle(action, delay, time){//函数节流 var timer = null, startTime = new Date(); return function(){ if(timer){ clearTimeout(timer); } var curTime = new Date(); var context = this, arg = arguments; if(curTime - startTime > time){ action.apply(context,arg); startTime = curTime; }else{ timer = setTimeout(function(){ action.apply(context,arg)//如果直接传arguments,到时打印出来的是undefined },delay) } } } var scrollFunc = debounce(function(a){ console.log(a); },500); var scrollThrottle = throttle(function(a){ console.log(a) },5000, 1000) window.onscroll = function(){ //scrollFunc(22); scrollThrottle(88) }