移动端图片滚动加载-lazyload实现的要点总结
最近在做移动端的营销页面时,遇到了页面有大量图片的情况,于是很自然的想到了要使用图片lazyload,PC端用着jQuery,也有现成的插件。
但是在移动端,基本不用jQuery,于是就试着自己去造一下轮子。
实现lazyload并不难,我很快就想到以下几个步骤:
- 首先HTML中不直接写图片真实URL,而是用一个空图代替,如<img class="lazy" src="data:images/nopic.png" data-original="images/test.jpg">
- 监听滚动scroll事件
- 判断图片元素是否出现在屏幕中,如果是则替换src为data-original里的真实URL。
在这简单的几个步骤中,也有几个细节要点需要注意:
- 监听事件是scroll,需要考虑是否应用函数节流(毕竟移动端,性能问题不能忘)
- 在移动端,水平X方向的滚动是很方便的,判断图片是否出现时,需要考虑水平方向。
- 滚动一定距离再刷新页面时,页面会有一次滚动,空图占据的大小若比真实图片大,就会出现在这一次判断中本来不会出现的图,替换真实图片重排后,高度减小,顶上来了。空图如果比真实图片小,就会加载还不应该出现的图,lazyload的效果就打折扣了。PC可直接写定px值,移动端需要使用相似比例的空图。
其中上面要点2比较坑。
垂直Y方向直接监听window的scroll即可,但水平X方向的多半是页面内某个元素设定了一定区域并overflow:auto; 偏偏页面内元素的scroll事件是不会冒泡的,事件的bubbles为false,即不可冒泡
默认的页面滚动事件是可冒泡的,由document开始触发,冒泡到window,事件的bubbles为true,即可冒泡,最坑的是获取和设置scrollTop等值时,却是使用 body 或 html 元素,水平有限,不理解为什么会是割裂开的。
对于这个问题,暂时没想到好的解决方案,暂时用写2次的方法解决,如lazyload(window),再lazyload('#container')监听各自的事件
而判断图片是否出现时,刚开始我是使用elem.offsetTop对比scrollTop,后来发现offsetTop是相对最近的定位元素的,很容易就坑了。
一番寻觅后才发现 elem.getBoundingClientRect(),一番查资料后总结了这个方法的一些要点
elem.getBoundingClientRect() 获取 元素相对于浏览器窗口的距离,会受到滚动的影响,实时获取,translate,scale等transform属性也会影响结果
getBoundingClientRect是DOM元素到浏览器可视范围的距离(不包含文档卷起的部分)。
该函数返回一个Object对象,该对象有6个属性:top,lef,right,bottom,width,height;
这里的top、left和css中的理解很相似,width、height是元素自身的宽高,
但是right,bottom和css中的理解有点不一样。right是指元素右边界距窗口最左边的距离,bottom是指元素下边界距窗口最上面的距离。
踩完一些坑后,总算仿照PC端的jQuery插件完成了轮子,代码如下
function lazyload(options){
var settings = {
selector : 'img.lazy',
container : window,
threshold : 0,
failurelimit : 0,
dataAttribute : "data-original",
};
if(typeof options == 'object'){
for(var key in options){
settings[key] = options[key] || settings[key];
}
}
var tId = null;
var imgsArr = Array.prototype.slice.call(document.querySelectorAll(settings.selector));
function inViewport(elem, threshold){
var o = elem.getBoundingClientRect();
var pageWidth = document.documentElement.clientWidth;
var pageHeight = document.documentElement.clientHeight;
threshold = threshold || pageHeight/5;
return o.left < pageWidth + threshold && o.top < pageHeight + threshold
}
function loadImg(){
clearTimeout(tId);
tId = setTimeout(function(){
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
var src = '';
var item = null;
var counter = 0;
if(imgsArr.length > 0){
for (var i = 0; i < imgsArr.length; i++) {
item = imgsArr[i];
if( inViewport(item) ){
src = item.getAttribute(settings.dataAttribute);
item.setAttribute('src', src);
imgsArr.splice(i,1);
i--;
counter = 0;
}else if( ++counter > settings.failurelimit ){
break;
}
};
}else {
settings.container.removeEventListener('scroll',loadImg);
}
}, 100);
}
loadImg();
settings.container.addEventListener('scroll',loadImg);
}
使用时和jQuery的lazyload插件类似,只是没有了$,直接使用函数lazyload();默认配置如下
lazyload({
selector : 'img.lazy', // 选择器
container : window, // 容器
threshold : 0, // 预留间距,即图片距离屏幕还有一定距离就预先加载
failurelimit : 0, // failurelimit,值为数字.lazyload默认在找到第一张不在可见区域里的图片时则不再继续加载,但当HTML容器混乱的时候可能出现可见区域内图片并没加载出来的情况,failurelimit意在加载N张可见区域外的图片,以避免出现这个问题.
dataAttribute : "data-original", // 存放真实URL的属性
});
以上实现还没有测试兼容,纯属交流,欢迎指正
移动端图片滚动加载-lazyload实现的要点总结的更多相关文章
- [js开源组件开发]图片懒加载lazyload
图片懒加载lazyload 前端对请求的一种优化方式,为什么叫懒加载,无从查起,反正我当初一直认为它是滚动加载的一种类型.它主要是以图片或背景在可视区域内时才显示真正的图片,减少src带来的负荷.所以 ...
- js插件---图片懒加载lazyload
js插件---图片懒加载lazyload 一.总结 一句话总结:使用异常简单,src里面放加载的图片,data-original里面放原图片,不懂的位置去官网或者github找API就好. 1.laz ...
- 图片懒加载--lazyload.js的用法
这几天公司的项目已经完成的差不多了,只剩下各种优化问题.今天着重于图片加载的优化.当一个页面需要下拉很长而且又有过多的图片要加载时,就会发生很多http请求,就会拉慢网页加载速度,用户体验不友好.怎么 ...
- 前端性能优化--图片懒加载(lazyload image)
话说前头: 上次写了一篇webpack的学习心得,webpack能做到提升前端的性能,其模块打包最终生成一个或少量的文件能够减少对服务端的请求.除此之外,本次的图片懒加载(当然不仅限于图片,还可以有视 ...
- 前端性能优化成神之路--图片懒加载(lazyload image)
图片懒加载(当然不仅限于图片,还可以有视频,flash)也是一种优化前端性能的方式.使用懒加载可以想要看图片时才加载图片,而不是一次性加载所有的图片,从而在一定程度从减少服务端的请求 什么是懒加载 懒 ...
- 前端实现图片懒加载(lazyload)的两种方式
在实际的项目开发中,我们通常会遇见这样的场景:一个页面有很多图片,而首屏出现的图片大概就一两张,那么我们还要一次性把所有图片都加载出来吗?显然这是愚蠢的,不仅影响页面渲染速度,还浪费带宽.这也就是们通 ...
- 插件:★★★ !!!图片懒加载 lazyload.js 、 jquery.scrollLoading.js
插件:图片懒加载 jquery.lazyload.js 2016-3-31 插件说明:http://www.w3cways.com/1765.html (小插件,好用) 下载地址: https://r ...
- 图片懒加载lazyload.js详解
简介 lazyload.js用于长页面图片的延迟加载,视口外的图片会在窗口滚动到它的位置时再进行加载,这是与预加载相反的. 优点 它可以提高页面加载速度: 在某些情况清晰它也可以帮助减少服务器负载. ...
- jQuery插件图片懒加载lazyload
来自XXX的前言: 什么是ImageLazyLoad技术 在页面上图片比较多的时候,打开一张页面必然引起与服务器大数据量的 交互.尤其是对于高清晰的图片,占的几M的空间.ImageLazyLoad技术 ...
随机推荐
- [c++] STL = Standard Template Library
How many people give up, because of YOU. Continue... 先实践,最后需要总结. 1. 数据流中的数据按照一定的格式<T>提取 ------ ...
- 自制jquery可编辑的下拉框
昨天看到QQ登录的时候,可以选择以前登录过的账户,这个东西也可以在网站登录的时候用到,所以我就想做一个这样的插件:在网上查了很多,没有找到合适自己的,所以决定自动制作一个. 原理就是一个textbox ...
- HTML Inspector – 帮助你编写高质量的 HTML 代码
HTML Inspector 是一款代码质量检测工具,帮助你编写更优秀的 HTML 代码.HTML Inspector 使用 JavaScript 编写,运行在浏览器中,是最好的 HTML 代码检测工 ...
- PHP类和对象函数实例详解
1. interface_exists.class_exists.method_exists和property_exists: 顾名思义,从以上几个函数的命名便可以猜出几分他们的功能.我想这也是我随着 ...
- 分享一个Jquery 分页插件 Jquery Pagination
分页插件来说,我觉得适用就行,尽量简单然后能够根据不同的应用场景能够换肤.展现形式等. 对于初学者想写分页插件的同学,也可以看下源码,代码也挺简单明了的,也助于自己写个小插件. 不过我比较懒,一般直接 ...
- javascript学习总结(三):如何较好的使用js。
1 假如浏览器不支持JavaScript怎么办? a.为什么浏览器会不支持?大部分浏览器都有禁用脚本的功能,例如chrome.b.在js被禁用的情况下要保证网页仍能实现它的核心功能(关键的用户需求) ...
- C#日期格式转换
DateTime dt = DateTime.Now; // Label1.Text = dt.ToString();//2005-11-5 13:21:25 // Label2.Text = dt. ...
- 【视频处理】YUV格式说明
YUV,是一种颜色编码方法,Y表示明亮度(Luminance.Luma),U和V则是色度.浓度(Chrominance.Chroma). YUV,Y`UV,YCbCr,YPbPr等都可以称为YUV,彼 ...
- LeetCode - 50. Pow(x, n)
50. Pow(x, n) Problem's Link ----------------------------------------------------------------------- ...
- 【转载】使用Lucene.NET实现数据检索功能
1.索引的管理 //指定索引库文件存放文件位置 FSDirectory directory = FSDirectory.Open(new DirectoryInfo(this.IndexDataDir ...