javascript 懒加载技术(lazyload)简单实现

1.前言
   懒加载技术(简称lazyload)并不是新技术, 它是js程序员对网页性能优化的一种方案.lazyload的核心是按需加载.在大型网站中都有lazyload的身影,例如谷歌的图片搜索页,迅雷首页,淘宝网,QQ空间等.因此掌握lazyload技术是个不错的选择,可惜jquery插件lazy load官网(http://www.appelsiini.net/projects/lazyload)称不支持新版浏览器。


2.lazyload在什么场合中应用比较合适?
   涉及到图片,falsh资源 , iframe, 网页编辑器(类似FCK)等占用较大带宽,且这些模块暂且不在浏览器可视区内,因此可以使用lazyload在适当的时候加载该类资源.避免网页打开时加载过多资源,让用户等待太久.


3.如何实现lazyload?
   lazyload的难点在如何在适当的时候加载用户需要的资源(这里用户需要的资源指该资源呈现在浏览器可视区域)。因此我们需要知道几点信息来确定目标是否已呈现在客户区,其中包括:
     1.可视区域相对于浏览器顶端位置
     2.待加载资源相对于浏览器顶端位置.

   在得到以上两点数据后,通过如下函数,便可得出某对象是否在浏览器可视区域了.
    //返回浏览器的可视区域位置
    function getClient(){
       var l,t,w,h;
       l  =  document.documentElement.scrollLeft || document.body.scrollLeft;
       t  =  document.documentElement.scrollTop || document.body.scrollTop;
       w =   document.documentElement.clientWidth;
       h =   document.documentElement.clientHeight;
       return {'left':l,'top':t,'width':w,'height':h} ;
    }

    //返回待加载资源位置
    function getSubClient(p){
       var l = 0,t = 0,w,h;
       w = p.offsetWidth ;
       h = p.offsetHeight;

       while(p.offsetParent){
        l += p.offsetLeft ;
        t += p.offsetTop ;
        p = p.offsetParent;
     }

     return {'left':l,'top':t,'width':w,'height':h } ;
  }

    其中 函数 getClient()返回浏览器客户区区域信息,getSubClient()返回目标模块区域信息。此时确定目标模块是否出现在客户区实际上是确定如上两个矩形是否相交.

    //判断两个矩形是否相交,返回一个布尔值
    function intens(rec1,rec2){
       var lc1,lc2,tc1,tc2,w1,h1;
       lc1 = rec1.left + rec1.width / 2;
       lc2 = rec2.left + rec2.width / 2;
       tc1 = rec1.top + rec1.height / 2 ;
       tc2 = rec2.top + rec2.height / 2 ;
       w1 = (rec1.width + rec2.width) / 2 ;
       h1 = (rec1.height + rec2.height) / 2;
       return Math.abs(lc1 - lc2) < w1 && Math.abs(tc1 - tc2) < h1 ;
    }

    现在基本上可以实现延时加载了,接下来,我们在 window.onscroll 事件中编写一些代码监控目标区域是否呈现在客户区.
     <div style = "width:100px; height:3000px"></div>
   <div id  = "d1" style = "width:50px; height:50px; background:red;position:absolute; top:1000px">
   </div>
    var d1 = document.getElementById("d1");
    window.onscroll = function(){
       var prec1 = getClient(); 
       var prec2 =  getSubClient(d1);
        if(intens(prec1,prec2)){
          alert("true")
        }
    }

   我们只需要在弹出窗口的地方加载我们需要的资源.
   这里值得注意的是:目标对象呈现在客户区域时,会随着滚动而不断的弹出窗口.因此我们需要在弹出第一个窗口后取消对该区域的监测,这里用一个数组来收集需要监测的对象,同时将监测的逻辑抽出来。同时需要注意 onscroll事件和onresize事件都会改变游览器可视区域信息,因此在该类事件触发后需要重新计算,这里用autocheck()函数实现.(迅雷首页的lazyload没有在onresize事件中重新计算目标对象是否在浏览器可视区域,因此如果先将浏览器窗口缩小到一定尺寸后滚动到需要加载图片的区域后点击最大化,图片加载不出来,呵呵,以后需要注意了).


   增加元素:<div id  = "d2" style = "width:50px; height:50px; background:blue;position:absolute; top:2500px">
 
    //比较某个子区域是否呈现在浏览器区域
    function jiance(arr,prec1,callback){
      var prec2;
      for(var i = arr.length - 1 ; i >= 0 ;i--){
        if(arr[i]){
         prec2 =  getSubClient(arr[i]);
         if(intens(prec1,prec2)){
            callback(arr[i]);
            //加载资源后,删除监测
            delete arr[i];
           }
        }
      }
    }
  
    //检测目标对象是否出现在客户区
    function autocheck(){
       var prec1 = getClient(); 
       jiance(arr,prec1,function(obj){

      //加载资源...
        alert(obj.innerHTML)
       })
    }
    //子区域一   
    var d1 = document.getElementById("d1");
    //子区域二
    var d2 = document.getElementById("d2");

   //需要按需加载区域集合
    var arr = [d1,d2];
    window.onscroll = function(){

     //重新计算
       autocheck();
    }

    window.onresize = function(){

     //重新计算
       autocheck();
    }
 
   现在我们只需要在弹窗的地方加载我们需要的资源了.源码就不贴出来了.如果需要的朋友,或着存在疑问的地方,可以联系我.

[原文:http://www.cnblogs.com/a_bu/archive/2011/01/16/1936989.html]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/547814.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ORACLE 全文搜索(精度高排前)

select * from tab_name order by decode(instr(id, ab), 0, 9999, instr(id, ab)), decode(instr(id, ab, 2), 0, 9999, instr(id, ab, 2)), id

HttpWebRequest模拟POST提交防止中文乱码

测试通过&#xff0c;请求的为自己写的一般处理程序&#xff0c;代码如下&#xff1a; 代码 Encoding myEncoding Encoding.GetEncoding("gb2312");stringparam HttpUtility.UrlEncode("aa", myEncoding) ""HttpUtility.UrlEncode("值A&quo…

笔试题--Multicore简答题(下)

1.面向对象的特征 封装封装&#xff0c;也就是把客观事物封装成抽象的类&#xff0c;并且类可以把自己的数据和方法只让可信的类或者对象操作&#xff0c;对不可信的进行信息隐藏。继承继承是指这样一种能力&#xff1a;它可以使用现有类的所有功能&#xff0c;并在无需重新编写…

手把手带你玩转Tensorflow 物体检测 API (1)——运行实例

本文在学习《Tensorflow object detection API 搭建属于自己的物体识别模型&#xff08;1&#xff09;——环境搭建与测试》的基础上优化并总结&#xff0c;此博客链接&#xff1a;https://blog.csdn.net/dy_guox/article/details/79081499&#xff0c;感谢此博客作者。 0.前言…

netframework 4.0内置处理JSON对象

前言 必须的是 .netframewoke 4.0的项目才能使用。 内容 1.项目添加System.Runtime.Serialization引用。 2.JsonHelper通用类的代码如下&#xff1a; using System;using System.Text;//--------------------------usingusing System.Runtime.Serialization.Json; // 添加引…

html5 java 图片上传_java实现图片上传至服务器并显示,如何做?希望要具体的代码实现...

展开全部有两种方法一是用上传的组建jspSmartUpload的Request&#xff0c;还有一种不用组建&#xff0c;但在e69da5e6ba9062616964757a686964616f31333238653233form表单中不能加入ENCTYPE "multipart/form-data "我给你的案例吧建立后台数据库if exists (select * f…

CISCO的GLBP(网关负载均衡协议)

名词定义&#xff1a;活动虚拟网关AVG: 它的优先级最高&#xff0c;应答所有ARP请求&#xff0c;反回哪个MAC地址&#xff0c;取决于采用的负载均衡方式AVG还给GLBP组中的每台路由器分配虚拟MAC地址&#xff0c;最多每个组可以分到4个&#xff0c;组里的每台路由器都被称为活动…

net发布的dll方法和类显示注释信息(字段说明信息)[图解]

自己发布的dll添加的另一个项目中突然没有字段说明信息了&#xff0c;给使用带来了很多的不便&#xff0c;原因是为了跨项目引用&#xff0c;所以导致不显示注释信息的&#xff0c;一下是解决这个问题的方法。 在要发布&#xff08;被引用&#xff09;的项目上右键 > 属性 &…

手把手带你玩转Tensorflow 物体检测 API (2)——数据准备

致谢声明 本文在学习《Tensorflow object detection API 搭建属于自己的物体识别模型&#xff08;2&#xff09;——训练并使用自己的模型》的基础上优化并总结&#xff0c;此博客链接&#xff1a;https://blog.csdn.net/dy_guox/article/details/79111949&#xff0c;感谢此博…

windows phone 学习(4)

1.Windows Phone8比Windows Phone7多了哪些&#xff1a;支持C&#xff08;组件级的补充&#xff0c;主体还是C#&#xff09;&#xff1b;采用Windows 8 SDK&#xff1b;更多API&#xff1b;2.普通的手机只能通过MarketPlace这个唯一的渠道下载安装软件,开发者帐户机制&#xff…

判断dll是版本(Debug Or Release)[测试通过]

简单的代码&#xff0c;google搜索提炼和分析&#xff0c;主要是利用反射技术&#xff0c;测试通过&#xff0c;抛砖引玉&#xff0c;自娱自乐&#xff0c;多多指教。 publicpartialclass_Default : System.Web.UI.Page{ protectedvoidPage_Load(objectsender, EventArgs e)…

手把手带你玩转Tensorflow 物体检测 API (3)——训练模型

致谢声明 本文在学习《Tensorflow object detection API 搭建属于自己的物体识别模型&#xff08;2&#xff09;——训练并使用自己的模型》的基础上优化并总结&#xff0c;此博客链接&#xff1a;https://blog.csdn.net/dy_guox/article/details/79111949&#xff0c;感谢此博…

动态类型var和dynamic和传统确定类型区别和效率

伴随着vs2010的出现&#xff0c;c#4.0的诞生&#xff0c;与之而来的动态类型dynamic更是给net程序员们锦上添花&#xff0c;为自己的程序书写上带来了给大的便利。可到底怎么用&#xff0c;好不好用&#xff0c;效率这么样&#xff0c;也许是大家最迫切关注的&#xff0c;msdn虽…

epel yum源

如果既想获得 RHEL 的高质量、高性能、高可靠性&#xff0c;又需要方便易用(关键是免费)的软件包更新功能&#xff0c;那么 Fedora Project 推出的 EPEL(Extra Packages for Enterprise Linux)正好适合你。EPEL(http://fedoraproject.org/wiki/EPEL) 是由 Fedora 社区打造&…

Windows 7 设置devenv.exe启动版本

我机子上装了有vs 05、vs 08、vs 10如果按上顺序安装的话&#xff0c;在 运行 > devenv 就可以打开最新的vs10 工具&#xff0c;如果顺序是乱的话&#xff0c;就没那么幸运了&#xff0c;也就是说你最后安装的版本将会被你的 devenv 命令打开&#xff0c;原因是最后一次安装…

手把手带你玩转Tensorflow 物体检测 API (4)—— 模型验证

致谢声明 本文在学习《Tensorflow object detection API 搭建属于自己的物体识别模型&#xff08;2&#xff09;——训练并使用自己的模型》的基础上优化并总结&#xff0c;此博客链接&#xff1a;https://blog.csdn.net/dy_guox/article/details/79111949&#xff0c;感谢此博…

java 获得文件的行数据_Java 读取文件指定行数据

public class ReadFileDemo1 {/*** 获取错误文件中的记录号* param sourceFile* return*/public static int[] readBadFile(String sourceFile){FileReader in null;LineNumberReader reader null;int[] array new int[0];try {//获取文件总行数long totalLine Files.lines…

几款浏览器JavaScript调试工具

WEB开发工具的使用已经非常普及&#xff0c;如果想要更方便于开发的话&#xff0c;不妨看看本文介绍的15款基于浏览器扩展的WEB开发工具。 1.Firebug Firebug是一款基于Firefox的浏览器扩展组件&#xff0c;它集成了网页CSS &#xff0c;文档对象模型( DOM )和JavaScript调试技…

mysql tomcat列表增删改查_Tomcat-Database

Tomcat-Database介绍根据Tomcat9源码二次开发&#xff0c;增加数据库功能&#xff0c;可一行代码实现CURD安装教程需要先配置Ant&#xff0c;然后在根目录下执行ant命令&#xff0c;即可编译&#xff0c;编译后的目录在Tomcat-Database/output/build下&#xff0c;其中在bin下可…

fatal error C1010: unexpected end of file while looking for precompiled head

致命错误C1010&#xff1a;在寻找预编译指示头文件时&#xff0c;文件未预期结束。 就是没有找到预编译指示信息的头文件。 问题一般发生在&#xff1a;通过添加文件的方式&#xff0c;添加了一些cpp文件到一个MFC的程序&#xff0c;但该cpp文件并不是MFC&#xff0c;而是标准…