移动端图片滚动加载-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技术 ...
随机推荐
- php分享(三十五) 文件多写注意事项
1: resource fopen ( string $filename , string $mode [, bool $use_include_path = false [,resource $co ...
- iOS_UIImge_Gif的展示
github地址: https://github.com/mancongiOS/UIImage.git 方式一: 用动画展示 UIImageView *gifImageView = [[UIImage ...
- MyBaits一对一的查询方法
MyBaits一对一的查询方法 一:表数据与表结构 CREATE TABLE teacher( t_id INT PRIMARY KEY AUTO_INCREMENT, t_name ) ); CRE ...
- Azure ARM (7) ARM Template - 使用Visual Studio编辑
<Windows Azure Platform 系列文章目录> 之前介绍的ARM Template,都是使用文本编辑器来编辑JSON文件的. 文本讲介绍如何使用Visual Studio, ...
- HTML5五种客户端离线存储方案
最近折腾HTML5游戏需要离线存储功能,便把目前可用的几种HTML5存储方式研究了下,基于HT for Web写了个综合的实例,分别利用了Cookie.WebStorage.IndexedDB以及Fi ...
- angularJs案例汇总
---恢复内容开始--- 这里我会把学习过程中碰到的demo与大家分享,由浅入深,逐个分析. Eg1:入门必备 <html ng-app="todoApp"> < ...
- 设置与获取Cookie
自己编写的一个Cookie设置与获取函数,大家有什么感觉需要改进的地方,请告知与我,我一定虚心接受. JavaScript - Code: function setCookie(name,value, ...
- LeetCode - Balanced Binary Tree
题目: Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced bin ...
- C# 模拟提交 Form表单的数据
用 HttpWebRequest Post方法模拟提交Form表单数据时,需要设置 ContentType 为 "application/x-www-form-urlencoded" ...
- ASP.NET MVC在线预览Excel、Word、TXT、PDF文件
代码: using System; using System.Collections.Generic; using System.Linq; using System.Web; using Syste ...