当前位置 主页 > 网站技术 > 代码类 >

    基于纯JS实现多张图片的懒加载Lazy过程解析(2)

    栏目:代码类 时间:2019-11-08 21:01

    //这里使用了utils工具类中的offset方法,具体实现看下面源码
    var A = utils.offset(curImgPar).offsetTop + curImgPar.offsetHeight;

    B:代表一屏幕距离+滚动条滚动距离

    //这里使用了utils工具类中的win方法,具体实现看下面源码
    var B = utils.win("clientHeight") + utils.win("scrollTop");

    当A < B的时候,此时懒加载的默认图片才能完整显示出来,这个时候就需要触发图片懒加载

    4)加载图片的时候,有渐进显示图片效果

    思路,利用window.setInterval 方法,通过对当前图片的透明度属性(curImg.style.opacity) 从透明0开始到透明度1,变化总时间为500ms即可

    // ->实现渐现效果
    function fadeIn(curImg) {
      var duration = 500, // 总时间
      interval = 10, //10ms走一次
      target = 1; //总距离是1
      var step = (target / duration) * interval; //每一步的步长
      var timer = window.setInterval(function () {
        var curOp = utils.getCss2SS(curImg, "opacity");
        if (curOp >= 1) {
          curImg.style.opacity = 1;
          window.clearInterval(timer);
          return
        }
        curOp += step;
        curImg.style.opacity = curOp;
      }, interval);
    }

    五、完整代码

    1)main.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <!--做移动端响应式布局页面,都需要加下面的meta-->
      <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!--meta:vp+tap一键生成-->
      <title>多张图片的延迟加载</title>
      <style type="text/css">
        * {
          margin: 0;
          padding: 0;
          font-family: "Microsoft Sans Serif";
          font-size: 14px;
        }
        ul, li {
          list-style: none;
        }
        img {
          display: block;
          border: none;
        }
        .news {
          padding: 10px;
        }
        .news li {
          position: relative;
          height: 60px;
          padding: 10px 0;
          border-bottom: 1px solid #eee;
        }
        .news li > div:first-child {  /*意思是,li下面的子div,中的第一个*/
          position: absolute;
          top: 10px;
          left: 0;
          width: 75px;
          height: 60px;
          background: url("./img/loading.PNG") no-repeat center center #e1e1e1;
          background-size: 100% 100%;
        }
        /*移动端布局,最外层容器是不设置宽高的*/
     
        .news li > div:first-child img {
          display: none;
          width: 100%;
          height: 100%;
          opacity: 0; /*这里设置为0的目的是,实现渐进的效果,后面的fadeIn函数,作用就是让图片透明都从0变成1*/
        }
     
        .news li > div:nth-child(2) {
          height: 60px;
          margin-left: 80px;
        }
        .news li > div:nth-child(2) h2 {
          height: 20px;
          line-height: 20px;
          /*实现文字超出一行自动裁切*/
          overflow: hidden;
          text-overflow: ellipsis; /*超出部分省略号显示*/
          white-space: nowrap; /*强制不换行*/
        }
        .news li > div:nth-child(2) p {
          line-height: 20px;
          font-size: 12px;
          color: #616161;
        }
      </style>
    </head>
    <body>
      <ul  class="news">
        <!--<li>-->
          <!--<div>-->
            <!--<img src="./img/new1.PNG" alt="">-->
          <!--</div>-->
          <!--<div>-->
            <!--<h2>香港四大家族往事,香港四大家族往事,香港四大家族往事</h2>-->
            <!--<p>香港四大家族往事:李嘉诚为郑裕彤扶灵香港四大家族往事:李嘉诚为郑裕彤扶灵</p>-->
          <!--</div>-->
        <!--</li>-->
      </ul>
     
     
     
     
    <script type="text/javascript" src="./tool/utils.js"></script>
    <script type="text/javascript">
      var news = document.getElementById("news"),
        imgList = news.getElementsByTagName("img");
     
      // 1、获取需要绑定的数据(通过Ajax)
      var jsonData = null;
      ~function () {
        // 1)首先创建一个Ajax对象
        var xhr = new XMLHttpRequest;
        // 2)打开我们需要请求的数据的那个文件地址
        // URL地址后面加随机数目的:清除每一次请求数据时候(get请求)产生的缓存
        // 因为每次访问的地址不一样,样浏览器就不会尝试缓存来自服务器的响应,读取本地缓存的数据。
        xhr.open('get', 'json/newsList.txt?' + Math.random(), false); // false代表同步
        // 3)监听请求的状态
        xhr.onreadystatechange = function () {
          if (xhr.readyState === 4 && /^2\d{2}$/.test(xhr.status)) {
            var val = xhr.responseText;
            jsonData = utils.jsonParse(val);
          }
        }
        // 4)发送请求
        xhr.send(null);
      }();
      console.log(jsonData);
     
      // 2、数据绑定(使用字符串拼接的方式)
      ~function () {
        var str = "";
        if (jsonData) {
          for (var i = 0, len = jsonData.length; i < len; i++) {
            var curData = jsonData[i];
            str += '<li>';
            str += '<div><img src="" trueImg="' + curData["img"] + '"></div>';
            str += '<div><h2>' + curData["title"] + '</h2>';
            str += '<p>' + curData["desc"] + '</p>';
            str += '</div>';
            str += '</li></div>';
          }
          news.innerHTML += str;
        }
      }();
     
      // 3、图片延迟加载
      // ->首先实现单张图片的延时加载
      function lazyImg(curImg) {
        var oImg = new Image;
        oImg.src = curImg.getAttribute("trueImg");
        oImg.onload = function() {
          curImg.src = this.src;
          curImg.style.display = "block";
          fadeIn(curImg);
          oImg = null;
        }
        curImg.isLoad = true;
      }
     
      // -> 循环处理每一张图片
      function handleAllImg() {
        for (var i = 0, len = imgList.length; i < len; i++) {
          var curImg = imgList[i];
          if (curImg.isLoad) { // 当前图片处理过的话,就不需重新进行处理
            continue;
          }
     
          // ->只有当A小于B的时候再进行处理
    //     var A = utils.offset(curImg).top + curImg.offsetHeight; // 这里A不能这么计算,因为此时图片是隐藏的,没有图片,他的offsetHeight当让也是为0
                                       // 如果我要的到图片的A值,我们可以通过拿到他父节点的容器就行了,哈哈
          var curImgPar = curImg.parentNode,
            A = utils.offset(curImgPar).offsetTop + curImgPar.offsetHeight,
            B = utils.win("clientHeight") + utils.win("scrollTop");
          if (A < B) {
            lazyImg(curImg);
          }
        }
      }
     
      // ->实现渐现效果
      function fadeIn(curImg) {
        var duration = 500, // 总时间
          interval = 10, //10ms走一次
          target = 1; //总距离是1
        var step = (target / duration) * interval; //每一步的步长
        var timer = window.setInterval(function () {
          var curOp = utils.getCss2SS(curImg, "opacity");
          if (curOp >= 1) {
             curImg.style.opacity = 1;
             window.clearInterval(timer);
             return
          }
          curOp += step;
          curImg.style.opacity = curOp;
        }, interval);
      }
     
      // 4、开始的时候(过500ms)加载1屏幕的图片,当滚动条滚动的时候,加载其他图片
      window.setTimeout(handleAllImg, 500);
      window.onscroll = handleAllImg;
       
    </script>
    </body>
    </html>