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

JS实现图片延迟加载

2015-08-25 18:13 190 查看

JS实现图片延迟加载

在一些图片比较多的网站,往往会出现这样的问题:由于页面中的图片资源多,加上网速的不给力,导致页面的图片迟迟加载不出来,或者所有的图都是加载到半张的样子,让人非常不爽,这种情况导致了非常差的用户体验,最终会让用户失去耐心,使得该网站的流量流失,现在我们就来探讨一下如何解决这个问题。

思路:

页面加载的时候,只加载出现在浏览器可视区域的图片,页面下方的图片先不进行加载;

往下滚动页面,下方的图片出现的时候(在本例子中是出现一半以后),对图片资源进行加载。

效果展示:

页面初始化的时候:



可以看到,第二排图片由于还有一半以上没有出现在浏览器可视区域内,所以还没有加载。



从开发者工具可以看到,此时页面只加载到01-03三张图片资源。

页面往下滚的时候:





可以看到,随着页面的往下滚动,页面下方的图片资源陆续被加载出来。

具体的实现:

1、页面结构

图片采用3列布局,共5行,当然,这个布局是可以按自己具体的需求来定。其中图片标签img的src先置为空,并另外设置一个自定义属性x-src,用于暂时存放图片的路径,这样,页面加载的时候,因为src属性为空,所有图片默认都不会加载到图片资源。

<div class="container-fluid div-border" id="img_wraper">

<div class="row clearfix">
<div class="col-md-4">
<a href="#" class="thumbnail img_container">
<img src="" x-src="img/01.jpg"/>
</a>
</div>
<div class="col-md-4">
<a href="#" class="thumbnail img_container">
<img src="" x-src="img/02.jpg"/>
</a>
</div>
<div class="col-md-4">
<a href="#" class="thumbnail img_container">
<img src="" x-src="img/03.jpg"/>
</a>
</div>
</div>

<div class="row clearfix">
<div class="col-md-4">
<a href="#" class="thumbnail img_container">
<img src="" x-src="img/04.jpg"/>
</a>
</div>
<div class="col-md-4">
<a href="#" class="thumbnail img_container">
<img src="" x-src="img/05.jpg"/>
</a>
</div>
<div class="col-md-4">
<a href="#" class="thumbnail img_container"><
4000
/span>
<img src="" x-src="img/06.jpg"/>
</a>
</div>
</div>

<div class="row clearfix">
<div class="col-md-4">
<a href="#" class="thumbnail img_container">
<img src="" x-src="img/07.jpg"/>
</a>
</div>
<div class="col-md-4">
<a href="#" class="thumbnail img_container">
<img src="" x-src="img/08.jpg"/>
</a>
</div>
<div class="col-md-4">
<a href="#" class="thumbnail img_container">
<img src="" x-src="img/09.jpg"/>
</a>
</div>
</div>

<div class="row clearfix">
<div class="col-md-4">
<a href="#" class="thumbnail img_container">
<img src="" x-src="img/10.jpg"/>
</a>
</div>
<div class="col-md-4">
<a href="#" class="thumbnail img_container">
<img src="" x-src="img/11.jpg"/>
</a>
</div>
<div class="col-md-4">
<a href="#" class="thumbnail img_container">
<img src="" x-src="img/12.jpg"/>
</a>
</div>
</div>

<div class="row clearfix">
<div class="col-md-4">
<a href="#" class="thumbnail img_container">
<img src="" x-src="img/13.jpg"/>
</a>
</div>
<div class="col-md-4">
<a href="#" class="thumbnail img_container">
<img src="" x-src="img/14.jpg"/>
</a>
</div>
<div class="col-md-4">
<a href="#" class="thumbnail img_container">
<img src="" x-src="img/15.jpg"/>
</a>
</div>
</div>

</div>


2、样式

为了方便,这里采用了Bootstrap的样式(需加载JQueryBootstrap),只需要把图片img的宽高设定为100%即可。

img {
width: 100% !important;
height: 100% !important;
}


另外,因为要通过判断图片距离浏览器可视区顶部的距离来决定图片是否加载,而页面刚加载的时候,图片还没载入,所占高度为0,这时就会导致所有图片都被判断为在浏览器可视区域内而全部加载,这时我们就需要事先给图片设定高度,但是这里由于是图片是响应式大小,不能给图片设定固定高度,我们可以给它的父容器,也就是a标签设定高度。然而,a标签的高度也是不定的,因为宽度会根据浏览器的宽度的变化而改变,但是图片的宽高比是一定的,在这里我们就可以用js为a标签定义高度。

//由于这个例子中的图片都是正方形,所以直接让a标签的高度等于它自己的宽度。
function setHeight() {
var imgWraper = document.getElementById('img_wraper');
var aImgCon = getElementsByClass(imgWraper, 'img_container');
for(var i = 0; i < aImgCon.length; i++) {
aImgCon[i].style.height = aImgCon[i].offsetWidth + 'px';
}
}


其中:getElementsByClass()方法是自定义的方法,可以根据元素的class名称获取元素,返回的是一个数组。关于该方法的详细介绍请移步js根据类名获取元素——自定义getElementsByClass()

3、逻辑

对页面中的每一张图片,我们都可以通过判断它在页面中的位置,准确来说是图片距离浏览器可视区域顶部的距离,如果图片距离顶部的距离+图片高度的一半<浏览器可视区域的高度,则从后台加载相应图片资源。

function delayImg() {
var aImg = document.getElementsByTagName('img');
var len = aImg.length;

for(var i = 0; i < len; i++) {
var thisImg = aImg[i];
if(thisImg.getAttribute('src') == '') {
if((thisImg.getBoundingClientRect().top + thisImg.offsetHeight / 2) <
document.documentElement.clientHeight) {
thisImg.setAttribute('src', thisImg.getAttribute('x-src'));
}
}
}
}


其中getBoundingClientRect()方法用于获取元素相对浏览器视窗的位置,相关用法可以参考getBoundingClientRect()方法中的介绍。

4、调用

最后,只需要在window的相应事件里面调用以上方法即可:

window.onload = function() {
setHeight();
delayImg();
};

window.onscroll = function() {
delayImg();
};

window.onresize = function() {
setHeight();
delayImg();
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息