如何实现瀑布流

实现瀑布流有两种方法。


HTML:

<div class="media-list waterfall" style="height: 100px;">
    <div class="media-image"><img src="images/img-1.jpg"></div>
    <div class="media-image"><img src="images/img-2.jpg"></div>
    <div class="media-image"><img src="images/img-3.jpg"></div>
    <div class="media-image"><img src="images/img-4.jpg"></div>
    <div class="media-image"><img src="images/img-5.jpg"></div>
    <div class="media-image"><img src="images/img-6.jpg"></div>
    <div class="media-image"><img src="images/img-7.jpg"></div>
    <div class="media-image"><img src="images/img-8.jpg"></div>
    <div class="media-image"><img src="images/img-9.jpg"></div>
    <div class="media-image"><img src="images/img-10.jpg"></div>
    <div class="media-image"><img src="images/img-11.jpg"></div>
    <div class="media-image"><img src="images/img-12.jpg"></div>
</div>


第一种,仅仅使用CSS即可实现

.media-list.waterfall{
  column-count: 3; //多列的列数
  column-gap: 20px; //列间距
  .media-image {
    break-inside: avoid;
    background-color: #5f5f5f;
    overflow: hidden;
    margin-bottom: 20px;
    border-radius: 5px;
    border: 1px solid #e7e7e7;
    img{
      max-width: 100%;
    }
    a:last-child{
      display: block;
      height: 22px;
      line-height: 22px;
      font-size: 12px;
      text-align: center;
    }
  }
}


使用这个方法内部组件的排列顺序是这样的:

如果你希望组件按照下面的顺序排列,就必须使用JavaScript了。




还是使用之前的html代码,样式如下:

.waterfall{
  width: 800px;
  margin-top: 50px;
  position:relative;
  background-size:contain;
  .media-image {
    float: left;
    width: 220px;
    position: absolute;
    img{
      width: 100%;
      height:100%;
      transition: 0.25s;
    }
  }
}


JavaScript 代码:

var items = document.getElementsByClassName('media-image');
//定义间隙10像素
var gap = 10;
//进页面执行函数
window.onload = function () {
  waterFall();
}


function waterFall() {
  //首先确定列数 = 页面的宽度 / 图片的宽度
  var pageWidth = 700;//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) {
      //满足这个条件则说明在第一行,文章里面有提到
      items[i].style.top = 0;
      items[i].style.left = (itemWidth + gap) * i + 'px';
      arr.push(items[i].offsetHeight);
    } else {
      //其他行,先找出最小高度列,和索引
      //假设最小高度是第一个元素
      var minHeight = arr[0];
      var index = 0;
      for (var j = 0; j < arr.length; j++) {//找出最小高度
        if (minHeight > arr[j]) {
          minHeight = arr[j];
          index = j;
        }
      }
      //设置下一行的第一个盒子的位置
      //top值就是最小列的高度+gap
      items[i].style.top = arr[index] + gap + 'px';
      items[i].style.left = items[index].offsetLeft + 'px';


      //修改最小列的高度
      //最小列的高度 = 当前自己的高度 + 拼接过来的高度 + 间隙的高度
      arr[index] = arr[index] + items[i].offsetHeight + gap;


      document.querySelector(".media-list.waterfall").style.height = arr[index] + 100 + "px";
    }
  }
}


//当页面尺寸发生变化时,触发函数,实现响应式
window.onresize = function () {
  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;
}


因为组件都是 postion:absolute 的,所以 div.waterfall 的高度是撑不起来的,需要手动指定div的高度。


参考:

https://zhuanlan.zhihu.com/p/55575862

修改时间 2021-06-01

真诚赞赏,手留余香
赞赏
随机推荐
Atom的php插件推荐
RESTful API 设计指南
Electron小试
详谈JavaScript数组合并常见几大方法
PS手绘20171008
nginx 代理
站着编程两年后我身体上的变化
函数限流,防止多次触发函数 Debounce 和 Throttle 的原理及实现
Wordpress REST API 开发
AES ECB CBC