您的位置:首页 > Web前端 > JavaScript

js 懒加载 getBoundingClientRect

2016-12-13 16:43 105 查看
首先熟悉一下es5的一个API

Range.getBoundingClientRect()

参考MDN兼容性:



返回一个 ClientRect 对象,该对象限定了选定的文档对象的内容,该方法返回了一个矩形,这个矩形包围了该文档对象中所有元素的边界矩形集合

比如一个html元素直接调用此API会得到这样的结果

ClientRect{
bottom:3669,
height: 523,
left: 8,
right: 756,
top: 3146,
width: 748,
__proto__: ClientRect
}


我这次只用到了top属性值,做了一个图片的懒加载,测试

分析一下懒加载用执行的JS流程

1.首先js查找所有需要做懒加载的图片。

2.当浏览器滚动的时候 for 或者forEach遍历图片的top偏移值,判断是否在当前的视窗内

a.如果是直接获取data属性值src,赋值给图片的src属性上面去

直接上html代码

html代码

<style>
img{height: 500px;overflow: hidden;background: #eee;margin-bottom: 20px;width: 100%}
</style>
<div>
<img data-src="http://10.148.60.59/mhb-media/images/offers/asia/campaign_gcw_room.jpg" alt="">
</div>
<div>
<img data-src="http://10.148.60.59/mhb-media/images/offers/asia/campaign_gcw_room.jpg" alt="">
</div>
<div>
<img data-src="http://10.148.60.59/mhb-media/images/offers/asia/campaign_gcw_room.jpg" alt="">
</div>
<div>
<img data-src="http://10.148.60.59/mhb-media/images/offers/asia/campaign_gcw_room.jpg" alt="">
</div>
<div>
<img data-src="http://10.148.60.59/mhb-media/images/offers/asia/campaign_gcw_room.jpg" alt="">
</div>
<div>
<img data-src="http://10.148.60.59/mhb-media/images/offers/asia/campaign_gcw_room.jpg" alt="">
</div>
<div id="img">
<img data-src="http://10.148.60.59/mhb-media/images/offers/asia/campaign_gcw_room.jpg" alt="">
</div>
<div>
<img data-src="http://10.148.60.59/mhb-media/images/offers/asia/campaign_gcw_room.jpg" alt="">
</div>


javascript部分

<script>
//查找所有图片元素
var img=document.querySelectorAll('img'),
//获取浏览器视窗的高度
height=document.body.clientWidth;

layzy();
//监听滚动条方法
window.onscroll=layzy;

function layzy(){
//遍历所有图片节点
for(var i=0;i<img.length;i++){
//闭包i,这里可以不用闭包。。。。
(function(index){
//获取当前遍历元素的top偏移值
var top=img[index].getBoundingClientRect().top;
//如果他的top值小于或等于视窗高度,则进入视窗
if(top<=height){
//显示图片
img[index].src=img[index].dataset.src
}
})(i)
}
}

</script>


最后要说的是,上面的代码显然不是很理想比如:

1.我们在window,监听滚动条的时候,很显然需要,用到一个节流函数比如underscroe 的throttle之类的,节省性能开支

2.在图片加载的的时候,其实应该加一个条件判断,判断图片是否加载完成,也就是说,为了访止相同的图片加载后,不再执行

比如在上面的匿名闭包中加上

function layzy(){
var self=this;
self.images = self.images || {};

for(var i=0;i<img.length;i++){
(function(index){
var top=img[index].getBoundingClientRect().top;
if(top<=height){
var curimg =img[index].dataset.src
var item = self.images[curimg] || new Image();
self.images[curimg] = item;

//判断图片是否已经加载完成,已经加载过此图片
if (self.images[curimg].complete) {
//....
}else{

}
}
})(i)
}
}


好吧,话说现在有新的API。可以更好的做懒加载,不过兼容性还不怎么理想。参考MDN给出的兼容提示

IntersectionObserver

Chrome 51.0以上版本

Firefox (Gecko) 52.0 (52.0)以上版本
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息