先说一下整体思路
图片链接存储在
data-lazy
中,当img
移动到屏幕可视区域后,触发loadImg()
,将data-lazy
赋值给img
的src
属性。从而加载图片。
HTML
<img class="image" src="" data-lazy="http://img.zcool.cn/community/01e3ad554425e20000019ae99db72a.jpg" style="width: 345px; height: 460px;" alt="">
实现方式如下
先监听屏幕的滚动事件调用
throttle()
window.onscroll = throttle(checkImgs());
throttle()
是一个节流操作,让高频连续触发的事件每隔一定的时间长度之后再做出响应。是有规律的时间间隔去执行。arguments、apply()
throttle(fn, mustRun = 500) {
var timer = null;
let previous = null;
return function() {
var now = new Date();
var context = this;
var args = arguments;
!previous ? previous = now : '';
var remaining = now - previous;
if (mustRun && remaining >= mustRun) {
fn.apply(context, args);
previous = now;
}
}
}
checkImgs()
中处理图片加载方法是否执行;查找并遍历需要缩放的所有图片,获取每个图片的实际宽度去与屏幕宽度做比较,若大于屏幕宽度则按图片的实际宽高比缩小图片,若小于屏幕宽度则居中。
checkImgs() {
var imgs = document.querySelectorAll('.image');
for (let i = this.imgIndex; i < imgs.length; i++) {
//图片等比缩放为视屏屏幕宽度
var screenWidth = document.getElementsByClassName('text')[0].clientWidth; //图片最大宽度
var imgWidth = parseFloat(imgs[i].style.width); //图片实际宽度
var imgHeight = parseFloat(imgs[i].style.height); //图片实际高度
var aspectRatio = imgWidth/imgHeight; //图片宽高比
if(imgWidth>=screenWidth){ //图片宽度大于等于屏幕宽度
imgs[i].style.width=screenWidth+'px';
imgs[i].style.height=screenWidth/aspectRatio+'px';
}else{ //图片宽度小于屏幕宽度居中
imgs[i].style.margin="0 auto";
}
//调用图片加载
this.isInSight(imgs[i])?(this.loadImg(imgs[i]),this.imgIndex = i):'';
}
}
isInSight(el)
判断图片是否在屏幕区域内。若返回true则触发loadImg()加载图片getBoundingClientRect()用法
isInSight(el) {
var bound = el.getBoundingClientRect(); //获取元素在页面位置
var clientHeight = window.innerHeight; //获取窗口高度
return bound.top <= clientHeight;
}
loadImg()
加载图片,从img
的data
属性中提取图片地址,并赋值给img
标签的src
,进而触发图片的onload
方法。
图片加载成功不予考虑,若加载失败的处理为:
1.在图片的onerror
函数中创建div
,用于在图片加载失败后替换img
标签。内容为点击重新加载
2.给此div
添加点击事件,隐藏div
并为img
的src
属性重新赋值,进而触发图片重新加载。若图片加载继续失败,则重新显示div
。
loadImg(el) {
var origin = window.location.origin+window.location.pathname;
if (el.src == origin) {
var source = el.dataset.lazy;
el.src = source;
//图片加载失败
el.onerror=function(){
var newItem=document.createElement('DIV');
newItem.className = 'errorImg';
newItem.innerHTML='请点击重新加载图片';
newItem.style.cssText="color:#666666;"+"width:"+el.clientWidth+"px;"+"height:"+el.clientHeight+"px;"+"line-height:"+el.clientHeight+"px;"
var parent = el.parentNode;
parent.lastChild == el ? parent.appendChild(newItem) : parent.insertBefore(newItem,el.nextSibling);
// 加载失败后重新点击
newItem.onclick=function(){
// el.src=source;
el.src=el.dataset.lazy; //重新为img的src属性赋值
newItem.style.display='none';
el.style.display='block';
el.onerror=function(){
newItem.style.display='block';
el.style.display='none';
};
}
el.style.display='none';
newItem.style.display='block';
}
}
}