[转]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/vipstone/archive/2011/01/17/1937055.html,如需转载请自行联系原作者

目录
相关文章
|
18天前
|
Web App开发 JavaScript 前端开发
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念,包括事件驱动、单线程模型和模块系统;探讨其安装配置、核心模块使用、实战应用如搭建 Web 服务器、文件操作及实时通信;分析项目结构与开发流程,讨论其优势与挑战,并通过案例展示 Node.js 在实际项目中的应用,旨在帮助开发者更好地掌握这一强大工具。
39 1
|
2月前
|
JavaScript 前端开发 中间件
探索后端技术:Node.js与Express框架的完美融合
【10月更文挑战第7天】 在当今数字化时代,Web应用已成为日常生活不可或缺的一部分。本文将深入探讨后端技术的两大重要角色——Node.js和Express框架,分析它们如何通过其独特的特性和优势,为现代Web开发提供强大支持。我们将从Node.js的非阻塞I/O和事件驱动机制,到Express框架的简洁路由和中间件特性,全面解析它们的工作原理及应用场景。此外,本文还将分享一些实际开发中的小技巧,帮助你更有效地利用这些技术构建高效、可扩展的Web应用。无论你是刚入门的新手,还是经验丰富的开发者,相信这篇文章都能为你带来新的启发和思考。
|
2月前
|
JavaScript 前端开发 API
探索后端技术:Node.js的优势和实际应用
【10月更文挑战第6天】 在当今数字化时代,后端开发是任何成功软件应用的关键组成部分。本文将深入探讨一种流行的后端技术——Node.js,通过分析其核心优势和实际应用案例,揭示其在现代软件开发中的重要性和潜力。
152 2
|
20天前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
29 5
|
1月前
|
移动开发 前端开发 JavaScript
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
于辰在大学期间带领团队参考网易游戏官网的部分游戏页面,开发了一系列前端实训作品。项目包括首页、2021校园招聘页面和明日之后游戏页面,涉及多种特效实现,如动态图片切换和人物聚合效果。作品源码已上传至CSDN,视频效果可在CSDN预览。
32 0
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
|
1月前
|
JavaScript 前端开发 中间件
JS服务端技术—Node.js知识点
本文介绍了Node.js中的几个重要模块,包括NPM、Buffer、fs模块、path模块、express模块、http模块以及mysql模块。每部分不仅提供了基础概念,还推荐了相关博文供深入学习。特别强调了express模块的使用,包括响应相关函数、中间件、Router和请求体数据解析等内容。文章还讨论了静态资源无法访问的问题及其解决方案,并总结了一些通用设置。适合Node.js初学者参考学习。
36 1
|
2月前
|
前端开发 JavaScript 安全
JavaScript前端开发技术
JavaScript(简称JS)是一种广泛使用的脚本语言,特别在前端开发领域,它几乎成为了网页开发的标配。从简单的表单验证到复杂的单页应用(SPA),JavaScript都扮演着不可或缺的角色。
26 3
|
2月前
|
缓存 前端开发 JavaScript
探索JavaScript的现代前端技术:从基础到进阶
探索JavaScript的现代前端技术:从基础到进阶
58 1
|
2月前
|
JavaScript 前端开发
JS懒加载
JS懒加载
28 0
|
4月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习中的图像识别技术深入理解Node.js事件循环及其在后端开发中的应用
【8月更文挑战第27天】本文将介绍深度学习中的图像识别技术,包括其原理、应用领域及未来发展。我们将探讨如何通过神经网络实现图像识别,并分析其在医疗、交通等领域的应用。最后,我们将展望图像识别技术的发展前景。