图片懒加载实现原理 JS

一、什么事图片懒加载(滚动加载)?

    通俗讲:当访问一个页面的时候,先把img或是其他元素的背景图片路径替换成一张1*1px图片的路径(这样就只需请求一次),只有当图片出现在浏览器的可视区域内时,才设置图片真正的路径,让图片显示出来。这就是图片的懒加载。

二、为什么要使用图片懒加载?

    比如一个页面上有很多图片,比如京东、淘宝首页等等,如果一上来就发送这么多请求,页面加载就很漫长,如果js文件都放在了文档的底部,恰巧页面的头部又依赖这个js文件,那就不好办了,更要命的是一上来就发送百八十个请求,服务器就吃不消了。

    优点:不仅可以减轻服务器的压力,而且可以让加载好的页面更快的呈现在用户面前。(用户体验好)

三、怎么实现?

  1、页面中的img元素,如果没有src属性,浏览器就不会发出请求去下载图片了,一旦通过JS设置了图片路径,浏览器才会送请求。

  2、如何获取真正的路径?这个简单,现在将真正的路径放在“data-url” (这个名字自己起就行)属性中,要用的时候就取出来,再设置。

  3、开始比较之前,先了解一些基本知识,比如如何获取某个元素的尺寸大小、滚动条滚动距离及偏移位置距离。

  1)屏幕可视窗口大小:对应于图中1、2位置处

  原生方法:window.innerHeight 标准浏览器及IE9+ || document.documentElement.clientHeight 标准浏览器及低版本IE标准模式 || document.body.clientHeight低版本混杂模式

  jQuery方法: $(window).height() 

  2)浏览器窗口顶部与文档顶部之间的距离,也就是滚动条滚动的距离:也就是图中3、4位置处

  原生方法:window.pageYOffset 标准浏览器及IE9+ || document.documentElement.scrollTop  标准浏览器及低版本IE标准模式 || document.body.scrollTop低版本混杂模式

  jQuery方法:$(document).scrollTop(); 

  3)获取元素的尺寸:对应于图中5、6位置处,左边是jQuery,右边是原生js

  $(o).width() = o.style.width;

  $(o).innerWidth() = o.style.width + o.style.padding;

  $(o).outerWidth() = o.offsetWidth = o.style.width + o.style.padding + o.style.border;

  $(o).outerWidth(true) = o.style.width + o.style.padding + o.style.border + o.style.margin;

  注意:要使用原生的style.xxx方法获取属性,这个元素必须已经有内嵌样式,如<div style="...."></div>;

  如果原先是通过外部或内部样式表定义css样式,必须使用o.currentStyle[xxx] || document.defaultView.getComputedStyle(0)[xxx]来获取样式值

  4)获取元素的位置信息:对应于图中7、8位置处

  返回元素相对于文档顶部、左边的距离。

  jQuery: $(o).offset().top 元素距离文档顶的距离    $(o).offset().left 元素距离文档左边缘的距离

  原生:getOffsetTop()

  顺便提一下返回元素相对于第一个已定位的父元素的偏移距离,注意与上面偏移距离的区别:

  jQuery : position()返回一个对象,$(o).position().left = style.left , $(o).position().top = style.top;

四、知道如何获取元素尺寸、偏移距离,接下来一个问题就是:如何判断一个元素进入或即将进入可视窗口区域?通过一张图来说明。

  1)外面最大的框为实际页面的大小,中间浅蓝色的框代表父元素的大小,对象1~8代表元素位于页面上的实际位置;下面以水平方向来做说明。

  2)对象8相对于页面左边界的偏移距离(offsetLeft)大于父元素右边界相对于页面左边界的偏移距离,此时可判读元素位于父元素之外;

  3)对象7左边界跨过了父元素右边界,此时:对象7左边界相对于页面左边界的偏移距离(offsetLeft)小于父元素相对于页面左边界的偏移距离,因此对象7就进入了父元素可视区;

  4)对象6的右边界相对于页面左边界的偏移距离 大于 父元素左边界相对于页面左边界的偏移距离,此时可判断元素进入父元素的可视区;

  5)对象5的右边界相对于页面左边界的偏移距离 小于 父元素左边界相对于页面左边界的偏移距离,此时可判断元素处于父元素可视区外。

  6)因此水平方向必须满足2个条件,才能说明元素位于父元素的可视区内,同理垂直方向也必须满足两个条件。

五、原生JS实现方法

<script>
    var imgs = document.getElementsByTagName("img");
    //获取可视区的高度与滚动条的偏移量
    function lazyload(){
      var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
      var viewportSize = window.innerHeight || document.documentElement.cllientHeight || document.body.clientHeight;
      for(var i=0;i<imgs.length;i++){
         var x = scrollTop + viewportSize - imgs[i].offsetTop;
         if(x>0){
            imgs[i].src = imgs[i].getAttribute("loadpic");
       }
   }
}

setInterval(lazyload , 1000);
</script>    

参考  http://www.cnblogs.com/jxlwqq/p/4318979.html

         http://www.cnblogs.com/flyromance/p/5042187.html

 

原文地址:https://www.cnblogs.com/qducn/p/7419196.html