[JavaScript] pure JS achieve multiple images of lazy loading Lazy (with source code)

An effect is shown below

 

FIG above effect, the effect of the following requirements

        1, when not loaded images, the default display Load picture background

        2, has just begun to enter the page, automatically loads the first screen of the picture

        3, the pull-down interface, when the container is completely reveal a picture screen, the picture is loaded immediately, replacing background

        4, when loading the picture, there is a progressive display picture effect

 

 

Second, the difficulty

        1) How Ajax request data

        2) How to dynamically bind json data to the html.

        3) How to calculate the positioning of the picture, the picture trigger lazy loading mechanism

        4) bonus items, there is now a gradual transition animation when displaying pictures

 

 

Third, pre-knowledge

        1) Ajax-related knowledge, XMLHttpRequest object, all modern browsers support this object.

        2) innerHTML, data binding, stitching string

        3) HTML DOM getAttribute () method returns the value of the custom property attribute name (attribute value is mainly used to return the custom property)

        4) Pictures of the onload event, when the src attribute of the attribute value of the correct picture (that is able to successfully load the picture), in order to trigger the image onload event

 

 

Fourth, the difficulties one by one break

        1) How Ajax request data

        Four steps

// 1) First, create an Ajax object
var xhr = new XMLHttpRequest;
// 2) Open the file that we need to address the requested data
// URL address followed by a random number added: Clear cache each time data request (get request) generated
// Because the address of each visit is different, kind of browser will not attempt to cache the response from the server reads the local cache of data.
xhr.open ( '? json / newsList.txt' 'get', + Math.random (), false); // false behalf of sync
 // 3) status is listening for requests
xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && /^2\d{2}$/.test(xhr.status)) {
        var val = xhr.responseText;
        jsonData = utils.jsonParse(val);
    }
}
// 4) sends a request
xhr.send(null);

 

        2) How to dynamically bind json data to the html.

        The string concatenation method (most commonly used data binding mode), i.e., by using the innerHTML , string concatenation of the page elements, and then re-render the page

var str = "";
if (jsonData) {
    for (var i = 0, len = jsonData.length; i < len; i++) {
        was 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;
}    

        Advantages : The most common way data binding, because the browser only needs to render once (the principle of all template data binding engine is the string concatenation, vue, angular, jade, kTemplate.js etc.)
                   prior to stitching good content, and finally unified added to the page, only trigger a reflow

        Drawbacks : We added a new string to # ul1 with, the original mouse over effect of three li disappeared (the original label binding events are gone)
                   original, oUl.innerHTML the role of the original label manner to fetch strings, originally as a label when things corresponding event has no binding, and then string concatenation,
                   however, after the completion of splicing, or string! And finally the unification add a string to the page, the browser also need to be rendered string corresponding label

 

        3) How to calculate the positioning of the picture, the picture trigger lazy loading mechanism ( the most critical point )

        Ideas:

                A: represents the distance from the top of the screen picture 

// offset method is used here in utils tools, source code embodied see below
var A = utils.offset(curImgPar).offsetTop + curImgPar.offsetHeight; 

                B: + represents a scroll bar to scroll the screen from a distance

The method used here // win utils tool class, source code embodied see below
var B = utils.win("clientHeight") + utils.win("scrollTop");

                When A <B time, in which case the default lazy loading of images to be displayed intact , this time on the need to trigger lazy loading images

 

        4) When loading images, display pictures have progressive effect

        Ideas, window.setInterval using methods of the current picture by a transparency properties (curImg.style.opacity) starts from a transparent transparency to 0, the total time of 500ms to

// -> fade effect to achieve
function fadeIn(curImg) {
    var duration = 500, // total time
    interval = 10, // 10ms go again
    target = 1; // total distance is 1
    var step = (target / duration) * interval; // every step of step
    was h = 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);
}

 

 

Five complete code

        1)main.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <! - do page layout in response to the mobile terminal, you need to add the following meta ->
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!--meta:vp+tap一键生成-->
    <Title> lazy loading multiple pictures </ 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 {/ * mean, following the first sub-li div, in much the * /
            position: absolute;
            top: 10px;
            left: 0;
            width: 75px;
            height: 60px;
            background: url("./img/loading.PNG") no-repeat center center #e1e1e1;
            background-size: 100% 100%;
        }
        / * Mobile terminal layout, the outermost vessel is not set wide high * /

        .news li > div:first-child img {
            display: none;
            width: 100%;
            height: 100%;
            opacity: 0; / * where 0 is set for the purpose, to achieve a progressive effect, behind fadeIn function, the role is to make transparent images have become from 01 * /
        }

        .news li > div:nth-child(2) {
            height: 60px;
            margin-left: 80px;
        }
        .news li > div:nth-child(2) h2 {
            height: 20px;
            line-height: 20px;
            / * Text exceeds one line to achieve automatic cutting * /
            overflow: hidden;
            text-overflow: ellipsis; / * Display the excess ellipses * /
            white-space: nowrap; / * * not wrap force /
        }
        .news li > div:nth-child(2) p {
            line-height: 20px;
            font-size: 12px;
            color: #616161;
        }
    </style>
</head>
<body>
    <ul id="news" class="news">
        <!--<li>-->
            <!--<div>-->
                <!--<img src="./img/new1.PNG" alt="">-->
            <!--</div>-->
            <!--<div>-->
                <-! <H2> Hong Kong Legend of the past, the past four families in Hong Kong, Hong Kong past four families </ h2> ->
                <- <p> Hong Kong past four families:! Cheng Yu Tung Fu Ling Li Ka-shing is Hong Kong past four families: Li Ka-shing is the Cheng Yu Tung Fu Ling </ 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, the need to obtain binding data (via Ajax)
    was jsonData = null;
    ~function () {
        // 1) First, create an Ajax object
        var xhr = new XMLHttpRequest;
        // 2) Open the file that we need to address the requested data
        // URL address followed by a random number added: Clear cache each time data request (get request) generated
        // Because the address of each visit is different, kind of browser will not attempt to cache the response from the server reads the local cache of data.
        xhr.open ( '? json / newsList.txt' 'get', + Math.random (), false); // false behalf of sync
        // 3) status is listening for requests
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && /^2\d{2}$/.test(xhr.status)) {
                var val = xhr.responseText;
                jsonData = utils.jsonParse(val);
            }
        }
        // 4) sends a request
        xhr.send(null);
    }();
    console.log(jsonData);

    // 2, data binding (stitching mode string)
    ~function () {
        var str = "";
        if (jsonData) {
            for (var i = 0, len = jsonData.length; i < len; i++) {
                was 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, lazy loading images
    // -> First realization of a single image loading delay
    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;
    }

    // -> Loop handle each picture
    function handleAllImg() {
        for (var i = 0, len = imgList.length; i < len; i++) {
            was curImg imgList = [i];
            if (curImg.isLoad) {// if the current picture is processed, we do not need to reprocess
                continue;
            }

            // -> only when A is smaller than B, then processed
// var A = utils.offset (curImg) .top + curImg.offsetHeight; // A not so calculated here, because the picture is hidden, no pictures, so that is when his offsetHeight 0
                                                                      // A value if I want to picture, we can get a container of his parent's on the line, ha ha
            var curImgPar = curImg.parentNode,
                A = utils.offset(curImgPar).offsetTop + curImgPar.offsetHeight,
                B = utils.win("clientHeight") + utils.win("scrollTop");
            if (A < B) {
                lazyImg(curImg);
            }
        }
    }

    // -> fade effect to achieve
    function fadeIn(curImg) {
        var duration = 500, // total time
            interval = 10, // 10ms go again
            target = 1; // total distance is 1
        var step = (target / duration) * interval; // every step of step
        was h = 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, beginning (over 500ms) 1 Load picture screen, when the scroll bar to scroll the time, a different image
    window.setTimeout(handleAllImg, 500);
    window.onscroll = handleAllImg;
    
</script>
</body>
</html>

  

        2)utils.js

// to conflict with global variables, we use the Singleton pattern
was utils = {
  // jsonParse: converting a string to an object JSON format JSON format
  jsonParse: function (str) {
      was val = null;
       try {
          val = JSON.parse(str);
      } catch (e) {
          val = eval('(' + str + ')');
      }
      return val;
  },

  getCss2SS: function (belt, attr) {
      was val = zero, reg = null;
      if ('getComputedStyle' in window) {
          val = window.getComputedStyle (belt, null) [attr];
      } else {
          if (attr === 'opacity') {
              val = curEle.currentStyle [attr]; // -> Back alpha (opacity = 10)
              reg = /^alpha\(opacity=(\d+(?:\.\d+)?)\)$/i; // Get the number 10
              ? Val = reg.test (val) reg.exec (val) [1] / 100: 1 // super-powerful, used with test and exec! ! !
          }
          val = curEle.currentStyle [attr];
      }
      reg = /^-?\d+(\.\d+)?(px|pt|rem|em)?$/i; // matching case: a pure numerical value or with units
      return reg.test(val) ? parseFloat(val) : val;
  },

  offset: function (cycles) {
      the total leftover = null,
          totalTop = zero,
          Hair = curEle.offsetParent;
      // first of all conduct themselves accumulation
      totalLeft += curEle.offsetLeft;
      totalTop + = curEle.offsetTop;

      while (par) {
          if (navigator.userAgent.indexOf("MSIE 8.0") === -1) {
              // accumulation parent reference frame
              totalTop + = par.clientTop;
              totalLeft += par.clientLeft;
          }
          // offset accumulation parent reference itself
          totalTop + = par.offsetTop;
          totalLeft += par.offsetLeft;
          by = par.offsetParent;
      }
      console.log('offsetTop: ' + totalTop + ', offsetLeft: ' + totalLeft);
      were result = {};
      result.offsetTop = totalTop;
      result.offsetLeft = totalLeft;
      return result;
  },

  win : function(attr, value) {
      if (value === undefined) {
          return document.documentElement[attr] || document.body[attr];
      }
      document.documentElement[attr] = value;
      document.body[attr] = value;
  }
};

 

        3, json file

[{ "Img": "./ img / new1.PNG", "title": "1 power network strategy and" Thirteen Five "Fourteen grand strategy", "desc": "1 Internet is humanity's greatest twentieth century the invention of the Internet is the greatest invention of the twentieth century mankind "},
 { "Img": "./ img / new2.PNG", "title": "2 power network strategy and" Thirteen Five "Fourteen grand strategy", "desc": "2 The Internet is humanity's greatest twentieth century invention, the Internet is the greatest invention of the twentieth century mankind "},
 { "Img": "./ img / new3.PNG", "title": "3 network power strategy and" Thirteen Five "Fourteen grand strategy", "desc": "3 The Internet is humanity's greatest twentieth century invention, the Internet is the greatest invention of the twentieth century mankind "}
]

 

Guess you like

Origin www.cnblogs.com/pengshengguang/p/11669176.html