原生js实现瀑布流效果

本文介绍了一种使用原生JavaScript实现瀑布流布局的方法。通过动态调整元素的位置来达到美观的瀑布流效果,并考虑了浏览器窗口大小变化及滚动加载更多图片的情况。

原生js实现瀑布流效果

效果图:
在这里插入图片描述


代码:

<!-- 样式部分 -->
<style>
  * {
    margin: 0;
    padding: 0;
  }

  #box {
    position: relative;
    height: 1000px;
  }

  img {
    display: block;
    width: 220px;
    background-color: #ccc;
  }

  .item {
    box-shadow: 2px 2px 2px #999;
    position: absolute;
  }

</style>

<!-- html 部分 -->
<div id="box">
</div>

<!-- js 部分 -->
<script>
  var box = document.getElementById('box');
  var items = box.children;
  // 定义每一列之间的间隙 为10像素
  var gap = 10;

  function getRandom(min, max) {
    return Math.floor(Math.random() * (max - min) + min)
  }

  window.onload = function () {
    let box = document.documentElement.querySelector('#box')
    for (let i = 0; i < 50; i++) {
      let div = document.createElement('div')
      div.className = 'item'
      let img = document.createElement('img')
      img.style.height = getRandom(150, 300)
      div.appendChild(img)
      box.appendChild(div)
    }
    // 一进来就调用一次
    waterFall()
    // 封装成一个函数
    function waterFall() {
      // 1- 确定列数  = 页面的宽度 / 图片的宽度
      var pageWidth = getClient().width;
      var itemWidth = items[0].offsetWidth;
      var columns = parseInt(pageWidth / (itemWidth + gap));
      var arr = [];
      for (var i = 0; i < items.length; i++) {
        if (i < columns) {
          // 2- 确定第一行
          items[i].style.top = 0;
          items[i].style.left = (itemWidth + gap) * i + 'px';
          arr.push(items[i].offsetHeight);

        } else {
          // 其他行
          // 3- 找到数组中最小高度  和 它的索引
          var minHeight = arr[0];
          var index = 0;
          for (var j = 0; j < arr.length; j++) {
            if (minHeight > arr[j]) {
              minHeight = arr[j];
              index = j;
            }
          }
          // 4- 设置下一行的第一个盒子位置
          // top值就是最小列的高度 + gap
          items[i].style.top = arr[index] + gap + 'px';
          // left值就是最小列距离左边的距离
          items[i].style.left = items[index].offsetLeft + 'px';

          // 5- 修改最小列的高度
          // 最小列的高度 = 当前自己的高度 + 拼接过来的高度 + 间隙的高度
          arr[index] = arr[index] + items[i].offsetHeight + gap;
        }
      }
      box.style.height = Math.max.apply(null, arr) + 'px';
    }
    // 页面尺寸改变时实时触发
    window.onresize = function () {
      waterFall();
    };
    // 当加载到第30张的时候
    window.onscroll = function () {
      if (getClient().height + getScrollTop() >= items[items.length - 1].offsetTop) {
        // 模拟 ajax 获取数据
        var datas = [
        ];
        for (var i = 0; i < datas.length; i++) {
          var div = document.createElement("div");
          div.className = "item";
          div.innerHTML = '<img>';
          box.appendChild(div);
        }
        waterFall();
      }

    };
  };

  // clientWidth 处理兼容性
  function getClient() {
    return {
      width: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
      height: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
    }
  }
  // scrollTop兼容性处理
  function getScrollTop() {
    return window.pageYOffset || document.documentElement.scrollTop;
  }
</script>

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值