1:实际需求

大型网站往往很矛盾,想用户在首页看到更多东西,又不想浪费太多服务器流量。比如一个有3屏的首页。可能50%的用户进首页的目的是点击首页的连接,到子页面。

那么我们的网站却为100%的用户加载了 3个 屏幕的所有内容。如果可以按需加载内容。就可以节约更多资源,做更多好的应用。

2:解决方案

用客户端语言来判断用户当前的可视范围,只加载用户可视范围的内容。最主要的是图片。因为文字信息,相对较小,其他多媒体内容相对占用服务器流量更多。

3:演示例子(最后提供)

4:解析

首先我们要分析下,这个效果会有一个 最外面的容器。他包涵了里面需要延迟加载一些内容。容器一般可能是浏览器窗口本身(window),或者一个有滚动条的DIV。

OK,我们必须获取这个容器的一些参数。比如 可视宽度,可视高度,水平卷去宽度,垂直卷去高度。我使用下面的程序。

4.1:获取容器对象属性

_this.docInfo=function(){//获取容器的相关信息

var d={},db= (wf)? document.body : warpper,

dd=(wf) ? document.documentElement : warpper;

if(sys.ie){

d.offh=dd.offsetHeight;//可视区域H

d.offw=dd.offsetWidth;//可视区域W

}else{

if(wf){

d.offw=window.innerWidth;//可视区域H

d.offh=window.innerHeight;//可视区域W

}else{

d.offh=dd.offsetHeight;//可视区域H

d.offw=dd.offsetWidth;//可视区域W

}

}

d.jtop=(wf) ? db.scrollTop+dd.scrollTop : db.scrollTop ;//垂直卷去高度

d.jleft=(wf) ? db.scrollLeft+dd.scrollLeft : db.scrollLeft;//水平卷去宽度

//被卷去的宽度 window 使用两个相加 div的卷曲就直接使用scrollLeft就OK

$j("bbb").innerHTML=d.offh+','+d.offw+','+d.jtop+','+d.jleft

return d;

}

//注意在非IE 浏览器下 获取非window对象的可视区域 使用offsetHeight 和 offsetWidth (跟IE 一样)

//在非IE 下获取 window对象的可视区域 则要使用 window.innerWidth 和window.innerHeight

//也就是说在非IE 下的 window 和 非window 对象的 可视区域获取是不一样的。

4.2:获取加载内容的信息

我们主要获取加载对象距离 页面容器对象的距离 。

IE 6 7会有个BUG

wtop=sys.ie ? (sys.ie[1]=='6.0' || sys.ie[1]=='7.0') ? 0 : warpper.offsetTop : warpper.offsetTop,

wleft=sys.ie ? (sys.ie[1]=='6.0' || sys.ie[1]=='7.0') ? 0 : warpper.offsetLeft : warpper.offsetLeft,

getoff=function(o){//获取IMG对象的 offw and offh

o.innerHTML=(o.offsetTop-wtop) +','+ (o.offsetLeft-wleft);

return (o.offsetTop-wtop) +','+ (o.offsetLeft-wleft);

//注意 o.offsetTop 在chrome下要等window.onload以后才能正确获取

};

4.3:加载主程序

他主要负责加载当前在可视范围内对象。那么我们必须去遍历所有要加载的对象。判断对象是否在当前的加载中。

然后加载他。我下面会有一个图。(方法可能不太好)

_this.Load=function(){

var hereline=[];

hereline[1]=doc.offh+doc.jtop;

hereline[2]=doc.offw+doc.jleft;

for(i=0;i

if(imgs[i][1] != undefined){//判断当前对象是否已经加载过

var jj=hereline[1] - imgs[i][1] < doc.offh +130 && hereline[1] - imgs[i][1] > 0 ? true : false,

jjj=hereline[2] - imgs[i][2] < doc.offw +270 && hereline[2] - imgs[i][2] > 0 ? true : false;

if(jj && jjj){

imgall[i].innerHTML+='第'+(++j)+'个加载';

imgs[i][1]=undefined;

}

}

}

if( j >= imgs.length){//判断是否已经全部加载完毕

//取消时间绑定

alert("已经全部加载完成,程序将不再执行")

warpper.οnscrοll=null;

warpper.οnresize=null;

}

}

我不太喜欢我的判断程序,但是暂时没找到,或者我没理解更好的算法。所以就先用这个了。

大体的意思:用容器的可视高度+容器滚动高度 - 对象距离距离容器距离 > 容器可视 + 对象本身高或宽 就证明在加载范围。(绕口令)

我们还必须把 已经加载过的对象排除在外。因为加载过的对象也满足以上公式,同时也可以少判断一些。

imgs[i][1]=undefined;

if(imgs[i][1] != undefined){//判断当前对象是否已经加载过

特别注意(看图)

看上图 A B C D。 分别有4个不同的角露在了 可视范围内。所以这4个对象是需要加载的。

如果只考虑对象的某个点,或者某个线来判断对象是否在可视范围,可能带来不好的体验。

由于有上面这种情况,也给我们的编程(判断是否在可视范围内)增加了难度。

我上面的方法,是可以完成了。(如果有发现BUG ,请给我指点。其实我也有点晕了。)

最后还有几个技巧,比如

1:对象全部加载完了。就应该去掉容器对象事件触发。

2:尽量优化判断对象是否在可视范围,或者遍历的对象的算法。可以节约很多浏览器资源。

3:cloudgamer 还提到一个 延迟触发,就是快速的滑动滚动条,延迟一下也是一个小的优化。

5:推荐文章

cloudgamer 的 他讲的很详细,也比我做的要好。所以推荐去学习他的这个效果哦。很多东西我也借鉴他的。

还有就是感谢他的指点。 Lazyload 延迟加载效果

6:我的源码

lazyload

body{ margin:0px; padding:0; font-size:12px;}

.jelle_box{width:270px; height:129px; border:1px solid #CCC; float:left;}

(function(){

window.lazyload=function(){

var _this={},//方法集合

imgsurl=['baidu_logo_2.gif']//最开始是用来加载图片的。这里是需要加载图片的地址集合

imgs=[],//全部IMG 数据 格式为 [[url,offw,offh],[url,offw,offh]]

i=0,//循环变量

j=0,//判断当前的加载个数

warpper=document.getElementById('jelle_abcd'),//window,//容器对象

wf=(warpper==window) ? true : false;

doc={offw:0,offh:0,jtop:0,jleft:0},//包含一些 容器对象当前的一些属性

sys=(function(){//不必紧张这只是一个判断浏览器的函数,你可以使用很多方法来判断浏览器

var ua=navigator.userAgent.toLowerCase(),sys={};

sys.firefox=ua.match(/firefox\/([\d\.]+)/);

sys.ie=ua.match(/msie\s([\d\.]+)/);

sys.chrome=ua.match(/chrome\/([\d\.]+)/);

return sys;

})(),

$j=function(id){return document.getElementById(id);},

imgall=$j('aaa').getElementsByTagName('DIV'),

getoff=function(o){//获取IMG对象的 offw and offh

//alert(o.width)

o.innerHTML=(o.offsetTop-warpper.offsetTop) +','+ (o.offsetLeft-warpper.offsetLeft);

return (o.offsetTop-warpper.offsetTop) +','+ (o.offsetLeft-warpper.offsetLeft);

//注意 o.offsetTop 在chrome下要等window.onload以后才能正确获取

};

//o.offsetTop获取对象距离浏览器顶部的距离 必须减去外面容器的距离浏览器的距离。(如果使用window容器就不用了)

(function(){//初始化容器对象绑定事件==

if(wf){

window.οnscrοll=function(){_this.judge();};

window.οnresize=function(){_this.judge();};

}else{

warpper.οnscrοll=function(){_this.judge();}

warpper.οnresize=function(){_this.judge();}

}

window.οnlοad=function(){setTimeout(_this.judge,500);};

})()

//容器对象设置结束

for( i ; i

var arr=[],off;

off=getoff(imgall[i]);

//alert(off)

arr.push(imgsurl[0]);

arr.push((off.split(',')[0]));

arr.push((off.split(',')[1]));

imgs.push(arr);

}

_this.Load=function(){

var hereline=[];

hereline[1]=doc.offh+doc.jtop;

hereline[2]=doc.offw+doc.jleft;

for(i=0;i

if(imgs[i][1] != undefined){//判断当前对象是否已经加载过

var jj=hereline[1] - imgs[i][1] < doc.offh +130 && hereline[1] - imgs[i][1] > 0 ? true : false,

jjj=hereline[2] - imgs[i][2] < doc.offw +270 && hereline[2] - imgs[i][2] > 0 ? true : false;

if(jj && jjj){

imgall[i].innerHTML+='第'+(++j)+'个加载';

imgs[i][1]=undefined;

}

}

}

if( j >= imgs.length){//判断是否已经全部加载完毕

//取消时间绑定

alert("已经全部加载完成,程序将不再执行")

warpper.οnscrοll=null;

warpper.οnresize=null;

}

}

_this.docInfo=function(){//获取容器的相关信息

var d={},db= (wf)? document.body : warpper,

dd=(wf) ? document.documentElement : warpper;

if(sys.ie){

d.offh=dd.offsetHeight;//可视区域H

d.offw=dd.offsetWidth;//可视区域W

}else{

if(wf){

d.offw=window.innerWidth;//可视区域H

d.offh=window.innerHeight;//可视区域W

}else{

d.offh=dd.offsetHeight;//可视区域H

d.offw=dd.offsetWidth;//可视区域W

}

}

d.jtop=(wf) ? db.scrollTop+dd.scrollTop : db.scrollTop ;//垂直卷去高度

d.jleft=(wf) ? db.scrollLeft+dd.scrollLeft : db.scrollLeft;//水平卷去宽度

//被卷去的宽度 window 使用两个相加 div的卷曲就直接使用scrollLeft就OK

$j("bbb").innerHTML=d.offh+','+d.offw+','+d.jtop+','+d.jleft

return d;

}

//注意在非IE 浏览器下 获取非window对象的可视区域 使用offsetHeight 和 offsetWidth (跟IE 一样)

//在非IE 下获取 window对象的可视区域 则要使用 window.innerWidth 和window.innerHeight

//也就是说在非IE 下的 window 和 非window 对象的 可视区域获取是不一样的。

_this.judge=function(){//后来发现不用判断方向了

var d=_this.docInfo();

if( d.jtop != doc.jtop || d.jleft != doc.jleft || d.offw > doc.offw || d.offh > doc.offh){

//判断是否需要执行加载

//条件为 被卷去的 y x 变化 或者 窗口大小 发生变化触发

doc.jtop = d.jtop;

doc.offh = d.offh;

doc.jleft = d.jleft;

doc.offw = d.offw;

_this.Load();//加载程序

}

}

//setTimeout(_this.judge,500);//执行初始化加载

//setTimeout 防止onload 和 onscroll的重复执行

//也就是本来就有onscroll的时候 最先执行了onload

return _this;

}

})()

lazyload();

html文本延迟加载,LazyLoad 延迟加载(按需加载)相关推荐

  1. 【分享】LazyLoad延迟加载(按需加载)

    1:实际需求 大型网站往往很矛盾,想用户在首页看到更多东西,又不想浪费太多服务器流量.比如一个有3屏的首页.可能50%的用户进首页的目的是点击首页的连接,到子页面. 那么我们的网站却为100%的用户加 ...

  2. .NET中的按需加载/延迟加载 LazyT

    业务场景: 在项目开发中,经常会遇到特定的对象使用的加载问题,有的实例对象我们创建之后并非需要使用,只是根据业务场景来调用,所以可能会导致很多无效的实例加载 延迟初始化出现于.NET 4.0,主要用于 ...

  3. webpack2+angular2 按需加载,优化首屏速度

    1.Angular2的按需加载及延迟加载 1.1 根模块AppModule 假设按需加载的模块为LazyModule,首页模块为LoginModule,根模块为AppModule.首先在AppModu ...

  4. Webpack实战(九):实现资源按需加载-资源异步加载

    第八篇[<教你搞懂webpack如果实现代码分片(code splitting)>] (https://blog.csdn.net/lfcss/article/details/104099 ...

  5. HTML5 本地存储和内容按需加载的思路和方法

    HTML5 本地存储和内容按需加载的思路和方法 作者:佚名 字体:[增加 减小] 来源:互联网 时间:04-07 16:05:09 我要评论 本文将着重介绍HTML5本地存储和内容按需加载的思路和方法 ...

  6. 前端基础建设与架构10 代码拆分和按需加载:缩减 bundle size,把性能做到极致

    这一讲,我们将对代码拆分和按需加载这一话题进行解析. 随着 Webpack 等构建工具的能力越来越强,开发者在构建阶段可以随心所欲打造项目流程,代码拆分和按需加载技术在业界曝光量也越来越高.事实上,代 ...

  7. python 按需加载_基于python的opcode优化和模块按需加载机制研究(学习与个人思路)(原创)...

    基于python的opcode优化和模块按需加载机制研究(学习与思考) 姓名:XXX 学校信息:XXX 主用编程语言:python3.5 文档转换为PDF有些图片无法完全显示,请移步我的博客查看 完成 ...

  8. On-Demand Resources Guide中文版(按需加载资源--上)

    本文翻译由唧唧歪歪翻译自Apple文档 On-Demand Resources Guide On-Demand Resources Guide中文版(按需加载资源--下)包含管理按需加载资源.调试以及 ...

  9. ant design pro取消登录_JeecgBoot实战按需加载 Ant-Design-Vue和Icon

    一.Ant-Design-Vue 按需加载 1.创建js文件 src/components/lazy_antd.js import Vue from 'vue'// base library impo ...

  10. Ant-Design-Vue和Icon按需加载方案 - JeecgBoot实战

    JeecgBoot实战 - 按需加载方案 文章目录 JeecgBoot实战 - 按需加载方案 一.Ant-Design-Vue 按需加载 二.Icon按需加载 一.Ant-Design-Vue 按需加 ...

最新文章

  1. 开源仓库Harbor搭建及配置过程
  2. 重温强化学习之无模型学习方法:时间差分方法
  3. B10_NumPy数组操作、修改数组形状、翻转数组、修改数组维度、连接数组、分割数组、数组元素的添加与删除
  4. 把SAP云平台上创建的API proxy添加到API product里去
  5. 互联网晚报 | 3月27日 星期日 | 东航已正式启动理赔工作;第二部黑匣子数据存储单元外观较为完好,其他部分损毁严重...
  6. uvm 形式验证_谈一谈IC flow中的形式验证
  7. Android多媒体之视频播放器高级开发
  8. git rebase 两个交叉branch换基
  9. php xml 接口调用,php的SimpleXML方法读写XML接口文件实例解析
  10. sql server 小技巧(8) visual studio 2013里使用Sql server compact 4.0及发布问题处理
  11. android大智慧安装目录,大智慧文件目录
  12. 百度文库复制文字代码
  13. 微信手机端调试工具-微信Web开发者工具使用教程
  14. 单片机c语言小灯闪烁,单片机c语言闪烁灯程序.doc
  15. 微软放弃的游戏被他们复活了:Windows经典「三维弹球」现实版,CAD建模、Arduino编程、数控机床打造,硬核致敬童年...
  16. 正确认高分子PEG:识MTA mPEG,Myristic-acid PEG,肉豆蔻酸 PEG,PEG改性肉豆蔻酸
  17. 局域网IP不足解决方法
  18. Eclipse中LogCat打印出错信息分析
  19. 关于选择性起始位点的新方法之SEASTAR: systematic evaluation of alternative transcription start sites in RNA...
  20. 智能浇花系统(ESP8266+APP Inventor+DHT11)

热门文章

  1. 解决linux下访问https站点问题
  2. eclipse中自动生成javadoc文档的方法
  3. linux 驱动程序 设备模块 设备号 设备文件创建 设备注册 字符驱动设备分析
  4. SQLite异常:unsafenativemethods.sqlite3_open_interop
  5. COdeSmith的教程 CHM格式
  6. linux vi只写入1个字节,关于linux命令的说明(这是一个命令集)
  7. Unity工程导入到AndroidStudio的一些注意事项
  8. unity3D使用User32.dll
  9. 520超浪漫文艺表白,追求女神必备!!动态Html网页,无编程基础也可娱乐
  10. 51单片机怎么显示当前时间_我电脑时间显示坏了,怎么修改不了?该怎么办?详细图文教你解决...