原生JavaScript实现响应式瀑布流懒加载图片布局

原生JavaScript实现响应式瀑布流懒加载图片布局

part.1 项目简介

编辑器:Atom
版本管理:Git
代码托管:Github
目录结构:
9jDtx0.png

part.2 项目布局
<body>
    <h2>响应式瀑布流懒加载效果</h2>
    <div class="container" id="theContainer">
      <div class="box">
        <div class="inner-box">
          <img src="yys/cube.gif"  data-src="yys/1.jpg" alt="">
        </div>
      </div>
      <div class="box">
        <div class="inner-box">
          <img src="yys/cube.gif" data-src="yys/2.jpg" alt="">
        </div>
      </div>
      <div class="box">
        <div class="inner-box">
          <img src="yys/cube.gif" data-src="yys/3.jpg" alt="">
        </div>
      </div>
      <div class="box">
        <div class="inner-box">
          <img src="yys/cube.gif" data-src="yys/4.jpg" alt="">
        </div>
      </div>
      <div class="box">
        <div class="inner-box">
          <img src="yys/cube.gif"  data-src="yys/5.jpg" alt="">
        </div>
      </div>
      <div class="box">
        <div class="inner-box">
          <img src="yys/cube.gif" data-src="yys/6.jpg" alt="">
        </div>
      </div>
      <div class="box">
        <div class="inner-box">
          <img src="yys/cube.gif" data-src="yys/7.jpg" alt="">
        </div>
      </div>
      <div class="box">
        <div class="inner-box">
          <img src="yys/cube.gif" data-src="yys/8.jpg" alt="">
        </div>
      </div>
    </div>
</body>
part.2 样式
    *{
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    body{
      background: #ccc;
    }
    h2{
      text-align: center;
      padding-left: 20px;
      margin: 40px 0;
    }
    .container{
      width: 90%;
      margin: 0 auto;
      position: relative;
    }
    .container::after{
      content: "";
      display: block;
      clear: both;
    }
    .box{
      float: left;
      padding: 10px;
      margin: 1%;
      position: absolute;
    }
    .inner-box{
      background: white;
      padding: 5px;
    }
    /*极小屏幕*/
    @media only screen and (min-width: 768px) {
      .box{
        width: 50%;
      }
      .box img{
        width: 100%;
      }

    }
    /*小屏幕*/
    @media only screen and (max-width: 768px) {
      .box{
        width: 100%;
      }
      .box img{
        width: 100%;
      }

    }
    /*中等屏幕*/
    @media only screen and (min-width: 992px) {
      .box{
        width: 25%;
      }
      .box img{
        width: 100%;
      }

    }
part.3 瀑布流实现函数
function waterFall(oParentId){

      //用于保存每列高度的数组
      var colHeights = [];
      //所有Box的数组
      var Boxes = getAllBoxes(oParentId);

      //列数
      var colNum = getCol();

      for(var i=0;i<Boxes.length;i++){
        //当前图片的高度
        var oBoxHeight = Boxes[i].offsetHeight;
        //当前图片的宽度
        var oBoxWidth = Boxes[i].offsetWidth;


        if(i<colNum){
          //第一行图片直接排列
          Boxes[i].style.top = 0+'px';
          Boxes[i].style.left = i*oBoxWidth+'px';;
          colHeights[i] = oBoxHeight;
        }else{
          //从第二行开始,图片追加到高度最小的一列
          var minHeight = Math.min.apply(null,colHeights); //最小列的高度
          var minHeightCol = colHeights.indexOf(minHeight);//最小列
          //使用绝对定位,确定图片的位置
          Boxes[i].style.top = minHeight+'px';
          Boxes[i].style.left = minHeightCol*oBoxWidth+'px';
          //更新列高
          colHeights[minHeightCol]+=oBoxHeight;

        }

      }

    }
part.4 懒加载
//懒加载首屏数据
    function lazyLoad(){
      var boxes = getAllBoxes('theContainer');
      for(var j=0;j<boxes.length;j++){
        var oImg = new Image();
        image = boxes[j].children[0].children[0];
        oImg.src =image.getAttribute("data-src");
        oImg.onload=(function(){
          image.src = oImg.src;
          waterFall('theContainer');
        })();
      }
    }
    //懒加载新数据
    function getNewData(aData){
      aData.forEach(function(item){
        //给获取到的数据添加DOM结构
        var outer = document.createElement('div');
        var inner = document.createElement('div');
        var image = document.createElement('img');
        var parent = document.getElementById('theContainer');
        outer.className = 'box';
        inner.className = 'inner-box';
        image.src='yys/cube.gif';
        inner.appendChild(image);
        outer.appendChild(inner);
        parent.appendChild(outer);
        //懒加载新数据
        var oImg = new Image();
        oImg.src =item;
        oImg.onload=function(){
          image.src = oImg.src;
          waterFall('theContainer');
        }
      });
    }
part.5 事件监听
window.onload=function(){
      //页面加载完毕,开始懒加载图片
      lazyLoad();
    }

    window.onresize=function(){
      //改变窗口大小时,更新瀑布流状态
      waterFall('theContainer');
    }

    window.onscroll=function(){
      //监听屏幕滚动事件
      var _scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
      var _clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
      var _scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
      //判断屏幕是否滚动到底部
      if(_scrollTop+_clientHeight == _scrollHeight){
        getNewData(imgData);
        waterFall('theContainer');
      }
    }
part.6 工具函数
  //获取容器内所有box
    function getAllBoxes(parentId){

      var oParent = document.getElementById(parentId);
      var aBoxes = oParent.getElementsByClassName('box');
      return aBoxes;

    }

    //获取当前屏幕下box的列数
    function getCol(){

      var windowWidth = document.documentElement.clientWidth || document.body.clientWidth;
      if(windowWidth<768){

        return 1;

      }else if (windowWidth<992) {

        return 2;

      }else{

        return 4;

      }

    }

》》项目预览
》》》项目源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值