1.什么是lazy-loading
图片“懒加载”
为img标签src设置统一的图片链接,而将真实链接地址装在自定义属性中。
所以开始时候图片是不会加载的,我们将满足条件的图片的src重置为自定义属性便可实现延迟加载功能
2.实现方法
思想其实很简单,就是当图片相对于视口的距离小于视口高度的时候就置换图片的src!
而图片的相对于视口的距离用getBoundingClientRect()简直so easy。
3.demo代码
<!DOCTYPE html>
<html>
<head>
<title>lazy loading</title>
<style type="text/css">
img {
display: block;
margin: 600px 100px;
}
</style>
</head>
<body>
<div class="zone">
<img width="612" height="612" data-src="http://farm8.staticflickr.com/7060/6969705425_0905bf6bba_o.jpg" src="img/loading.png" class="lazy">
<img width="612" height="612" data-src="http://farm8.staticflickr.com/7203/6969484613_0ee3af0144_o.jpg" src="img/loading.png" class="lazy">
<img width="612" height="612" data-src="http://farm8.staticflickr.com/7207/6821596428_cdae70e306_o.jpg" src="img/loading.png" class="lazy">
<img width="612" height="612" data-src="http://farm8.staticflickr.com/7037/6965140403_9fbb5e7f96_o.jpg" src="img/loading.png" class="lazy">
</div>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript">
$(function() {
function loadImage (el, fn) {
src = el.getAttribute('data-src');
el.src = src;
fn? fn() : null;
}
function elementInViewport(el) {
var rect = el.getBoundingClientRect()
return (
rect.top >= 0 && rect.left >= 0 && rect.top <= (window.innerHeight || document.documentElement.clientHeight)
)
}
var query = $('.lazy'),
images = new Array(),
processScroll = function() {
for (var i = 0; i < images.length; i++) {
if (elementInViewport(images[i])) {
loadImage(images[i], function() {
images.splice(i, 1);
console.log(images.length)
});
}
};
};
for (var i = 0; i < query.length; i++) {
images.push(query[i]);
};
window.addEventListener('scroll', processScroll);
})
</script>
</body>
</html>
4.问题与优化
于是功能便实现了,但是其实也有很多问题,比如打开页面,然后又点去别的窗口,看了部av回来后本以为这个页面图片已经缓冲好了结果尼玛啊拉下去还是要重新加载....所以需要判断这种情况,今天没时间了以后再针对这个写一下吧。
5.参考资料
6.代码勘误
用for循环遍历的话,会有问题,因为数组也在动态的变化,
Javascript 在 for in 或 foreach 遍历中,会自动跳过 undefined 元素,而普通 for 遍历则不会。
processScroll = function() {
var len = images.length;
for (var i in images) {
if (elementInViewport(images[i])) {
loadImage(images[i], function() {
delete images[i];
console.log(i);
});
}
};
};