图片懒加载
什么是图片懒加载?
img元素在页面加载时并不加载实际的图片,只有当图片出现在浏览器的可视区域内时,才设置图片正真的路径,让图片显示出来。这就是图片懒加载
为什么要使用图片懒加载?
- 减轻服务器的压力
- 加速用户网页加载速度(用户体验好)
- 节省网络流量
经典使用场景:
- 淘宝首页
- 微信文章浏览页
思路
- 没有 src 属性的 img 元素,浏览器不会发出请求下载图片,一旦通过javascript设置了图片路径,浏览器才会送请求。有点按需分配的意思,你不想看,就不给你看,你想看了就给你看~
- 不设置 src 属性,我们怎么获取真实图片路径?我们可以使用自定义属性 data-src ,当图片进入可视区域时,将 data-src 的值设置给 src
如何判断元素是否进入可视区域?我们要先了解一些基本的知识,比如说如何获取某个元素的尺寸大小、滚动条滚动距离及偏移位置距离:
屏幕可视窗口大小:对应于图中1、2位置处 原生方法:
// 标准浏览器及IE9+ // 标准浏览器及低版本IE标准模式 // 低版本混杂模式 window.innerHeight || document.documentElement.clientHeight|| document.body.clientHeight
jQuery方法:
$(window).height()
浏览器窗口顶部与文档顶部之间的距离,也就是滚动条滚动的距离:也就是图中3、4处对应的位置; 原生方法:
// IE9+及标准浏览器 // 兼容ie低版本的标准模式 // 兼容混杂模式; window.pagYoffset|| document.documentElement.scrollTop|| document.body.scrollTop
jQuery方法:
$(document).scrollTop();
获取元素的尺寸:对应于图中5、6位置处;左边jquery方法,右边原生方法
$(o).width() // = o.style.width; $(o).innerWidth() // = o.style.width+o.style.padding; $(o).outerWidth() // = o.offsetWidth = o.style.width+o.style.padding+o.style.border; $(o).outerWidth(true) // = o.style.width+o.style.padding+o.style.border+o.style.margin;
- 获取元素的位置信息:对应与图中7、8位置处
$(o).offset().top // 元素距离文档顶的距离 $(o).offset().left // 元素距离文档左边缘的距离
然后就是判断元素是否进入可视区域
外面最大的框为实际页面的大小,中间浅蓝色的框代表父元素的大小,对象1~8代表元素位于页面上的实际位置;以水平方向来做如下说明!
- 对象8左边界相对于页面左边界的偏移距离(offsetLeft)大于父元素右边界相对于页面左边界的距离,此时可判读元素位于父元素之外;
- 对象7左边界跨过了父元素右边界,此时:对象7左边界相对于页面左边界的偏移距离(offsetLeft)小于 父元素右边界相对于页面左边界的距离,因此对象7就进入了父元素可视区;
- 在对象6的位置处,对象5的右边界与页面左边界的距离 大于 父元素左边界与页面左边界的距离;
- 在对象5位置处时,对象5的右边界与页面左边界的距离 小于 父元素左边界与页面左边界的距离;此时,可判断元素处于父元素可视区外;
- 因此水平方向必须买足两个条件,才能说明元素位于父元素的可视区内;同理垂直方向也必须满足两个条件;具体见下文的源码;
对于绝大数的网页(只可以垂直滚动的),我们可以使用简化的判断方式:只判断垂直偏移
这里给出只判断垂直偏移的简单实现
function isShow($node) {
var windowH = $(window).height();
var scrollTop = $(window).scrollTop();
var nodeOT = $node.offset().top;
var nodeH = $node.height();
return nodeOT <= scrollTop + windowH && nodeOT + nodeH >= scrollTop
}
实现
注意:因为 chrome 中onscroll时间太过于频繁,我们使用 setTimeout 进行延时处理
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<style>
.a {
height: 1000px;
}
img{
height: 394px;
width: 650px;
background: green;
}
</style>
</head>
<body>
<div class="a"></div>
<div class="a"></div>
<img data-src="http://static.mafengshe.com/home/pic/2.jpg?imageMogr2/quality/40" alt="">
<div class="a"></div>
<div class="a"></div>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script>
function isShow($node) {
var windowH = $(window).height();
var scrollTop = $(window).scrollTop();
var nodeOT = $node.offset().top;
var nodeH = $node.height();
return nodeOT <= scrollTop + windowH && nodeOT + nodeH >= scrollTop
}
window.onscroll = function(){
console.log(isShow($('img')))
isShow($('img')) && $('img').src = $('img').data('src');
}
</script>
</body>
</html>
在线预览效果在这里