JS 瀑布流

JS 瀑布流布局

今天我们来介绍一个流行的图片布局方式,常见于个人博客,以及一些图片素材网站上。
瀑布流是一种形象的称呼,大小不一的盒子就像拼图一样,一个个拼接而成,形成一个“瀑布”。

效果图

在这里插入图片描述

原理

html 部分我们将盒子设置为定位。子绝父相布局。
JS 部分我们可以将图片分成 3 列,当图片铺完第一行之后,我们设置left:0,从左边开始,利用判断语句查询最小高度的那一列,然后将图片放置到那一列。如此往复,就像拼图一样,瀑布流就产生了。

代码

<div class="all" id="all">
  <div class="imgbox">
    <img src="1.jpg" alt="" />
    <div class="article">
      要陪在值得的人身边一年又- -年十年又十年 愿去年所有的遗憾是今年惊喜的铺垫
      一眨眼就2021年了早知道我不眨眼了 2020实鼠不易,2021牛转乾坤。
      往后的日子是崭新的,谁也别回头看了。 有苦有甜才是生活,有悲有喜才是人生。
      凛冬散尽,星河长明,新的一年,万事顺遂。
    </div>
  </div>
  <div class="imgbox">
    <img src="20201215095457_4bbec.jpg" alt="" />
    <div class="article">
      事事有找落,件件有回音。 银河有迹可循,2020年的不快乐要后会无期。
      万物更新,旧疾当愈,长安常安。 如同梁.上燕岁岁常相见
      看我的大长腿一不小心跨了个年 我和你跨过分秒,愿也可以跨过余生岁月
      即使年年不见也要岁岁平安
    </div>
  </div>
  <!-- imgbox都是一样的,只是内容不一样,所以这里省略部分代码 -->
</div>
* {
  margin: 0;
  padding: 0;
}
body {
  width: 100%;
  background-color: #eee;
  font-size: 10px;
}
.all {
  width: 87em;
  position: relative;
  margin: 10px auto 0;
}
.imgbox {
  width: 29em;
  background-color: #fafafa;
  box-sizing: border-box;
  position: absolute;
  box-shadow: 0 0 10px #999;
}
img {
  width: 29em;
  display: block;
}
.article {
  width: 23em;
  font-size: 0.8em;
  line-height: 2.6em;
  margin: 30px auto;
}

html 与 css 都是基础知识,应该都看得懂,我就不再赘述了。

function waterfall() {
  // 自动计算图片+文字内容宽度
  var imgbox = document.getElementsByClassName('imgbox');
  var margin_top = 5; //第一列margin-top
  var margin_top2 = 5; //第二列margin-top
  var margin_top3 = 5; //第三列margin-top
  var arr = [0, 0, 0];

  for (var i = 0; i < imgbox.length; i++) {
    //获取最短的那一列的值
    var min = Math.min.apply(null, arr);
    // 获取它所在列
    var column = arr.indexOf(min);
    //如果在第一列
    if (column == 0) {
      arr[column] = min + imgbox[i].offsetHeight; //记录第一列高度
      imgbox[i].style.left = '0px'; //设置style样式

      //设置除第一行外的imgbox多往下挪动5px(产生点间隙,单纯为了美观)
      if (i > 2) {
        imgbox[i].style.top =
          arr[column] - imgbox[i].offsetHeight + margin_top + 'px';
        margin_top = margin_top + 5;
      }
    } else if (column == 1) {
      arr[column] = min + imgbox[i].offsetHeight; //记录第二列高度
      imgbox[i].style.left = imgbox[i - 1].offsetWidth + 5 + 'px';
      if (i > 2) {
        imgbox[i].style.top =
          arr[column] - imgbox[i].offsetHeight + margin_top2 + 'px';
        margin_top2 = margin_top2 + 5;
      }
    } else if (column == 2) {
      arr[column] = min + imgbox[i].offsetHeight; //记录第三列高度
      imgbox[i].style.left =
        imgbox[i - 1].offsetWidth + imgbox[i - 2].offsetWidth + 10 + 'px';
      if (i > 2) {
        imgbox[i].style.top =
          arr[column] - imgbox[i].offsetHeight + margin_top3 + 'px';
        margin_top3 = margin_top3 + 5;
      }
    }
  }
}

//加载完成后执行。
window.onload = function () {
  waterfall();
};

思路:
1、我们需要获取<div class=imgbox></div>的大小,利用offsetWidthoffsetHeight.
2、定义一个数组arr=[0,0,0],3 个数代表 3 列,每一列高度从 0 开始。
利用数组记录每一列的高度,然后利用Math.min.apply()方法去找出数组中最小的数,再去寻找最小值所在下标,可以用indexOf()方法,找出来的下标对应的即是所在列数 (列数从 0 开始数!)
3、利用循环,给每一列的每一个元素设置 style 样式。

注释我都添加在了每一行代码后边,大家自己练习的时候可以先在纸上写个大纲,免得写的时候逻辑混乱。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值