js图片预加载[解决图片加载闪烁问题]
1.预加载
原理:提前加载图片,当用户需要查看时可直接从本地缓存中渲染。
说白了就是提前请求图片,丢入缓存。
优点:能防止页面一次性向服务器响应大量请求(比如图片)导致服务器响应慢,页面卡顿或崩溃等问题
2.图片加载闪烁问题
问题说明:
图片未全部加载导致每次加载一部分后,父(div)高度被撑开,视觉上就有闪烁效果
解决思路:
图片全部加载完成前隐藏img标签,全部加载完成后显示img标签
代码如下:
//dom
<div id="img"></div>
//javascript
(function () {
var root=document.getElementById('img');
//创建Image实例
var imgObj = new Image()
//设置imgObj的图片url
imgObj.src = "http://img3.imgtn.bdimg.com/it/u=1362874374,2095103613&fm=26&gp=0.jpg"
if(imgObj.complete) { //complete属性:图片在浏览器中显示为true,隐藏为false
console.log('image completed'); //此处判断为了判断浏览器是否有该图片缓存,
return //若有缓存且显示在页面上,则complete==true
}
imgObj.style.display="none" //图片未完全加载完成前,隐藏该img标签,此时comlpete为false
root.append(imgObj) //将imgObj添加至div
imgObj.onload = function () { //onload事件:imgObj添加至div才触发function
console.log('图片加载完成')
imgObj.style.display="block" //此时图片已经全部加载,显示img标签,此时comlpete为true
}
})()
js图片懒加载
1.懒加载
原理:先将img标签中的src链接设为同一张图片(空白图片),将其真正的图片地址存储再img标签的自定义属性中(比如data-src)。当js监听到该图片元素进入可视窗口时,即将自定义属性中的地址存储到src属性中,达到懒加载的效果。
说白了就是用户看到哪,哪才开始加载图片。
优点:页面加载速度快、可以减轻服务器的压力、节约了流量,用户体验好
代码如下:
//dom
<img src=" " data-original="https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1566461767&di=5ba97d85d40b479b42c72d117e7dc150&src=http://b-ssl.duitang.com/uploads/item/201608/06/20160806232840_WZCjT.jpeg" lazyload="true">
<img src=" " data-original="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1566471835645&di=7913f41d4078b45ea89dc3edaeea6667&imgtype=0&src=http%3A%2F%2Fimg5.duitang.com%2Fuploads%2Fitem%2F201309%2F07%2F20130907222746_HBz3Y.jpeg" lazyload="true">
<img src=" " data-original="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1566471835644&di=bd940fd16e4dcfc761221e82ffc3be05&imgtype=0&src=http%3A%2F%2Fimg4q.duitang.com%2Fuploads%2Fitem%2F201505%2F06%2F20150506020234_whCsH.jpeg" lazyload="true">
<img src=" " data-original="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1566471835644&di=81a83caff324150d1f2661e4f6f864c3&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201505%2F06%2F20150506112302_hVdyf.jpeg" lazyload="true">
<img src=" " data-original="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1495432305,1781395839&fm=26&gp=0.jpg" lazyload="true">
<img src=" " data-original="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1566471835643&di=28c39320ea5f1e4927d2340892a2a069&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fblog%2F201504%2F28%2F20150428130413_MLsuj.jpeg" lazyload="true">
<img src=" " data-original="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1566471835643&di=27e580fe342f0fbbbc080b465fe1c748&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201702%2F15%2F20170215125428_LcCkF.jpeg" lazyload="true">
<img src=" " data-original="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1566471835642&di=d04da05ad35d0bb6496b30945bd60fee&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201505%2F06%2F20150506110441_2VBu4.jpeg" lazyload="true">
<img src=" " data-original="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1566471835642&di=19744548055ea26ae0b107a5a9198db8&imgtype=0&src=http%3A%2F%2Fimg4q.duitang.com%2Fuploads%2Fblog%2F201401%2F02%2F20140102122145_cVZim.jpeg" lazyload="true">
<img src=" " data-original="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1566471835643&di=bee616ac40cb432184b5291ab5f2fe66&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201505%2F06%2F20150506202306_WYEi5.jpeg" lazyload="true">
//javascript
function lazyLoad (time) {
// 获取所有要进行懒加载的图片
var eles = document.querySelectorAll('img[data-original][lazyload]')
Array.prototype.forEach.call(eles, function (item, index) {
var rect
if (item.dataset.original === '')
return
var viewHeight= document.documentElement.clientHeight+(document.body.scrollTop || document.documentElement.scrollTop) // 可视区域的高度,兼容移动端scrollTop
rect = item.offsetTop
// 图片一进入可视区,动态加载
if (rect < viewHeight) {
!function () {
var img = new Image()
img.src = item.dataset.original
item.style.visibility="hidden"
img.onload = function () {
item.src = img.src;
item.style.visibility="visible"
}
item.removeAttribute('data-original')
item.removeAttribute('lazyload')
}()
}
})
}
// 首屏要人为的调用,否则刚进入页面不显示图片,react:componentDidMount()
window.onload = function(){
lazyLoad();
}
//绑定滑动事件
//移动端
document.addEventListener('touchmove',lazyLoad)
//pc端
document.addEventListener('scroll', lazyLoad)
API:
页可见区域宽: document.body.clientWidth;
网页可见区域高: document.body.clientHeight;
网页可见区域宽: document.body.offsetWidth (包括边线的宽);
网页可见区域高: document.body.offsetHeight (包括边线的宽);
网页正文全文宽: document.body.scrollWidth;
网页正文全文高: document.body.scrollHeight;
网页被卷去的高: document.body.scrollTop;
网页被卷去的左: document.body.scrollLeft;
网页正文部分上: window.screenTop;
网页正文部分左: window.screenLeft;
屏幕分辨率的高: window.screen.height;
屏幕分辨率的宽: window.screen.width;
屏幕可用工作区高度: window.screen.availHeight;
scrollHeight: 获取对象的滚动高度。
scrollLeft:设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离
scrollTop:设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离
scrollWidth:获取对象的滚动宽度
offsetHeight:获取对象相对于版面或由父坐标 offsetParent 属性指定的父坐标的高度
offsetLeft:获取对象相对于版面或由 offsetParent 属性指定的父坐标的计算左侧位置
offsetTop:获取对象相对于版面或由 offsetTop 属性指定的父坐标的计算顶端位置
event.clientX 相对文档的水平座标
event.clientY 相对文档的垂直座标
event.offsetX 相对容器的水平坐标
event.offsetY 相对容器的垂直坐标
document.documentElement.scrollTop 垂直方向滚动的值