图片懒加载
在图片未到达可视区域时,先不请求图片,到达可视区域后再去请求图片,防止页面在初始化时加载大量的图片,影响页面的响应时间
实现方法:
- 先给img的src指定一个默认的图片地址(图片src不能为空,因为为空的话也会去请求)
- 给img添加一个自定义属性data-src,将图片真实的地址赋值给data-src;
- 给window添加一个onscroll事件,当滚动页面时,判断img标签是否在可视范围内,如果在,则将data-src中的地址赋值给src,便于去请求图片资源;
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
img {
display: block;
margin-bottom: 50px;
width: 400px;
height: 400px;
}
</style>
</head>
<body>
<img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt="">
<img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt="">
<img src="default.jpg" data-src="http://ww1.sinaimg.cn/large/006y8mN6gw1fa7kaed2hpj30sg0l9q54.jpg" alt="">
<img src="default.jpg" data-src="http://ww1.sinaimg.cn/large/006y8mN6gw1fa7kaed2hpj30sg0l9q54.jpg" alt="">
<img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt="">
<img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt="">
<img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt="">
<img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt="">
<img src="default.jpg" data-src="http://ww1.sinaimg.cn/large/006y8mN6gw1fa7kaed2hpj30sg0l9q54.jpg" alt="">
<img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt="">
<img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt="">
</body>
var num = document.getElementsByTagName('img').length;
var img = document.getElementsByTagName("img");
var n = 0; //存储图片加载到的位置,避免每次都从第一张图片开始遍历
lazyload(); //页面载入完毕加载可是区域内的图片
window.onscroll = lazyload;
function lazyload() { //监听页面滚动事件
var seeHeight = document.documentElement.clientHeight; //可见区域高度
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; //滚动条距离顶部高度
for (var i = n; i < num; i++) {
if (img[i].offsetTop < seeHeight + scrollTop) {
if (img[i].getAttribute("src") == "default.jpg") {
img[i].src = img[i].getAttribute("data-src");
}
n = i + 1;
}
}
}
为了防止在滚动到img的可视范围时,在一定时间内多次请求图片,需要添加节流函数,如下:
// 简单的节流函数
//fun 要执行的函数
//delay 延迟
//time 在time时间内必须执行一次
function throttle(fun, delay, time) {
var timeout,
startTime = new Date();
return function() {
var context = this,
args = arguments,
curTime = new Date();
clearTimeout(timeout);
// 如果达到了规定的触发时间间隔,触发 handler
if (curTime - startTime >= time) {
fun.apply(context, args);
startTime = curTime;
// 没达到触发间隔,重新设定定时器
} else {
timeout = setTimeout(fun, delay);
}
};
};
// 实际想绑定在 scroll 事件上的 handler
function lazyload(event) {
for (var i = n; i < imgNum; i++) {
if (img.eq(i).offset().top < parseInt($(window).height()) + parseInt($(window).scrollTop())) {
if (img.eq(i).attr("src") == "default.jpg") {
var src = img.eq(i).attr("data-src");
img.eq(i).attr("src", src);
n = i + 1;
}
}
}
}
// 采用了节流函数
window.addEventListener('scroll',throttle(lazyload,500,1000));
图片预加载
原理:将所有所需的图片提前加载到本地,在需要时,直接从本地缓存中取图片;
实现方式:new Image()
,然后使用onload()
事件回调预加载完成函数;当浏览器将图片下载到本地后,之后同样的src就直接使用缓存
1.无序加载
// 所有的图片(要是网络太好,自己加图片吧)
const imgs = [
"http://op2clp53n.bkt.clouddn.com/20161104122758_cap-hpi.jpg",
"http://op2clp53n.bkt.clouddn.com/500414621%20%281%29.jpg",
"http://op2clp53n.bkt.clouddn.com/cover_bg.png",
"http://img.aotu.io/mamboer/post-aotu.jpg",
"http://misc.aotu.io/o2/img/books/books-cover.jpg",
"http://img.aotu.io/Yettyzyt/cover.png",
"http://img.aotu.io/wengeek/responsive-image.png",
"https://gw.alicdn.com/tfs/TB1_6wnRXXXXXbwXFXXXXXXXXXX-900-500.jpg",
"http://op2clp53n.bkt.clouddn.com/_138.jpg",
"http://op2clp53n.bkt.clouddn.com/0_ocs_fin_cov_1.jpg",
"http://op2clp53n.bkt.clouddn.com/2voyage.jpg",
"http://op2clp53n.bkt.clouddn.com/boa_illustrations_master_fb_1200x628-12.jpg",
"http://op2clp53n.bkt.clouddn.com/building_science_bulletin_cover_2__1x.jpg",
"http://op2clp53n.bkt.clouddn.com/building-science-bulletin-cover_1x.jpg",
"http://op2clp53n.bkt.clouddn.com/chemistry4_1x.png",
"http://op2clp53n.bkt.clouddn.com/first_colony_dribbble_copy.jpg"
];
let len = imgs.length;
/**
* 遍历imgs数组,将所有图片加载出来
* 可以通过控制台查看网络请求,会发现所有图片均已加载
*/
for (let i = 0; i < len; i++) {
let imgObj = new Image(); // 创建图片对象
imgObj.src = imgs[i];
imgObj.addEventListener('load', function () { // 这里没有考虑error,实际上要考虑
console.log('imgs' + i + '加载完毕');
}, false);
}
2. 有序加载
// 所有的图片(要是网络太好,自己加图片吧)
const imgs = [
"http://op2clp53n.bkt.clouddn.com/20161104122758_cap-hpi.jpg",
"http://op2clp53n.bkt.clouddn.com/500414621%20%281%29.jpg",
"http://op2clp53n.bkt.clouddn.com/cover_bg.png",
"http://img.aotu.io/mamboer/post-aotu.jpg",
"http://misc.aotu.io/o2/img/books/books-cover.jpg",
"http://img.aotu.io/Yettyzyt/cover.png",
"http://img.aotu.io/wengeek/responsive-image.png",
"https://gw.alicdn.com/tfs/TB1_6wnRXXXXXbwXFXXXXXXXXXX-900-500.jpg",
"http://op2clp53n.bkt.clouddn.com/_138.jpg",
"http://op2clp53n.bkt.clouddn.com/0_ocs_fin_cov_1.jpg",
"http://op2clp53n.bkt.clouddn.com/2voyage.jpg",
"http://op2clp53n.bkt.clouddn.com/boa_illustrations_master_fb_1200x628-12.jpg",
"http://op2clp53n.bkt.clouddn.com/building_science_bulletin_cover_2__1x.jpg",
"http://op2clp53n.bkt.clouddn.com/building-science-bulletin-cover_1x.jpg",
"http://op2clp53n.bkt.clouddn.com/chemistry4_1x.png",
"http://op2clp53n.bkt.clouddn.com/first_colony_dribbble_copy.jpg"
];
let len = imgs.length;
/**
* 遍历imgs数组,有序将所有图片加载出来
* 可以通过控制台查看网络请求,会发现所有图片均按顺序加载
*/
let count = 0;
load();
function load() {
var imgObj = new Image();
imgObj.src = imgs[count];
$(imgObj).on('load error', function () { // 没错我使用了jQuery
console.log(count);
if (count >= len) {
console.log('加载完毕');
$('.container').addClass('active');
} else {
load(); // 继续加载下一张
}
count++;
});
}