图片懒加载实现原理 JS
一、什么事图片懒加载(滚动加载)?
通俗讲:当访问一个页面的时候,先把img或是其他元素的背景图片路径替换成一张1*1px图片的路径(这样就只需请求一次),只有当图片出现在浏览器的可视区域内时,才设置图片真正的路径,让图片显示出来。这就是图片的懒加载。
二、为什么要使用图片懒加载?
比如一个页面上有很多图片,比如京东、淘宝首页等等,如果一上来就发送这么多请求,页面加载就很漫长,如果js文件都放在了文档的底部,恰巧页面的头部又依赖这个js文件,那就不好办了,更要命的是一上来就发送百八十个请求,服务器就吃不消了。
优点:不仅可以减轻服务器的压力,而且可以让加载好的页面更快的呈现在用户面前。(用户体验好)
三、怎么实现?
1、页面中的img元素,如果没有src属性,浏览器就不会发出请求去下载图片了,一旦通过JS设置了图片路径,浏览器才会送请求。
2、如何获取真正的路径?这个简单,现在将真正的路径放在“data-url” (这个名字自己起就行)属性中,要用的时候就取出来,再设置。
3、开始比较之前,先了解一些基本知识,比如如何获取某个元素的尺寸大小、滚动条滚动距离及偏移位置距离。
1)屏幕可视窗口大小:对应于图中1、2位置处
原生方法:window.innerHeight 标准浏览器及IE9+ || document.documentElement.clientHeight 标准浏览器及低版本IE标准模式 || document.body.clientHeight低版本混杂模式
jQuery方法: $(window).height()
2)浏览器窗口顶部与文档顶部之间的距离,也就是滚动条滚动的距离:也就是图中3、4位置处
原生方法:window.pageYOffset 标准浏览器及IE9+ || document.documentElement.scrollTop 标准浏览器及低版本IE标准模式 || document.body.scrollTop低版本混杂模式
jQuery方法:$(document).scrollTop();
3)获取元素的尺寸:对应于图中5、6位置处,左边是jQuery,右边是原生js
$(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;
注意:要使用原生的style.xxx方法获取属性,这个元素必须已经有内嵌样式,如<div style="...."></div>;
如果原先是通过外部或内部样式表定义css样式,必须使用o.currentStyle[xxx] || document.defaultView.getComputedStyle(0)[xxx]来获取样式值
4)获取元素的位置信息:对应于图中7、8位置处
返回元素相对于文档顶部、左边的距离。
jQuery: $(o).offset().top 元素距离文档顶的距离 $(o).offset().left 元素距离文档左边缘的距离
原生:getOffsetTop()
顺便提一下返回元素相对于第一个已定位的父元素的偏移距离,注意与上面偏移距离的区别:
jQuery : position()返回一个对象,$(o).position().left = style.left , $(o).position().top = style.top;
四、知道如何获取元素尺寸、偏移距离,接下来一个问题就是:如何判断一个元素进入或即将进入可视窗口区域?通过一张图来说明。
1)外面最大的框为实际页面的大小,中间浅蓝色的框代表父元素的大小,对象1~8代表元素位于页面上的实际位置;下面以水平方向来做说明。
2)对象8相对于页面左边界的偏移距离(offsetLeft)大于父元素右边界相对于页面左边界的偏移距离,此时可判读元素位于父元素之外;
3)对象7左边界跨过了父元素右边界,此时:对象7左边界相对于页面左边界的偏移距离(offsetLeft)小于父元素相对于页面左边界的偏移距离,因此对象7就进入了父元素可视区;
4)对象6的右边界相对于页面左边界的偏移距离 大于 父元素左边界相对于页面左边界的偏移距离,此时可判断元素进入父元素的可视区;
5)对象5的右边界相对于页面左边界的偏移距离 小于 父元素左边界相对于页面左边界的偏移距离,此时可判断元素处于父元素可视区外。
6)因此水平方向必须满足2个条件,才能说明元素位于父元素的可视区内,同理垂直方向也必须满足两个条件。
五、原生JS实现方法
<script>
var imgs = document.getElementsByTagName("img");
//获取可视区的高度与滚动条的偏移量
function lazyload(){
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
var viewportSize = window.innerHeight || document.documentElement.cllientHeight || document.body.clientHeight;
for(var i=0;i<imgs.length;i++){
var x = scrollTop + viewportSize - imgs[i].offsetTop;
if(x>0){
imgs[i].src = imgs[i].getAttribute("loadpic");
}
}
}
setInterval(lazyload , 1000);
</script>
参考 http://www.cnblogs.com/jxlwqq/p/4318979.html
http://www.cnblogs.com/flyromance/p/5042187.html