瀑布流布局js实现

瀑布流的特点是每个项的宽度一致,高度不同,每次把图片添加到高度最低的一列以降低最后整体的高度差

瀑布流最好的方式是使用js计算高度差。但是也可以纯css实现,有兴趣可以看看//www.greatytc.com/p/d6a6efc7ec15 

本文主要列举两种js的实现方式

一.使用position定位实现

要点:每次找到列的高度最小的一列,把图片添加到列高最小的一列,以降低各列之间的高度差。

实现:设置父元素定位为相对定位,图片的的定位是绝对定位,计算图片的top值和left值

效果:


代码:

<!DOCTYPE html>

<html>

  <head>

    <meta charset="utf-8" />

    <meta name="viewport" content="width=device-width,initial-scale=1.0" />

    <title>ttt</title>

    <style>

      * {

        margin: 0;

        padding: 0;

        border: 0;

      }

      #app {

        width: calc(100% - 100px);

        height: auto;

        border: 1px solid #000;

        box-sizing: content-box;

        margin: 0 auto;

        position: relative;

        /* font-size: 0; */

      }

      .item {

        display: inline-block;

        box-sizing: border-box;

        position: absolute;

        height: auto;

        border: 1px solid #000;

        vertical-align: text-top;

        overflow: hidden;

      }

      .item > img {

        width: 100%;

      }

    </style>

    <script

      type="text/javascript"

      src="http://ajax.googleapis.com/ajax/libs

/jquery/1.4.0/jquery.min.js"

    ></script>

  </head>

  <body>

    <div id="app">

      <div class="item">

        <img src="./image/male.png" alt="" />

      </div>

      <div class="item">

        <img src="./image/male.png" , alt="" />

      </div>

      <div class="item">

        <img src="./image/东丽区.png" , alt="" />

      </div>

      <div class="item">

        <img src="./image/定西市.png" , alt="" />

      </div>

      <div class="item">

        <img src="./image/中心城区.png" , alt="" />

      </div>

      <div class="item">

        <img src="./image/中心城区.png" , alt="" />

      </div>

      <div class="item">

        <img src="./image/定西市.png" , alt="" />

      </div>

      <div class="item">

        <img src="./image/中心城区.png" , alt="" />

      </div>

      <div class="item">

        <img src="./image/male.png" alt="" />

      </div>

    </div>

    <script>

      $(document).ready(function() {

        function getMinIndex(columTotalHeight) {

          let min = Math.min.apply(null, columTotalHeight)

          let index = columTotalHeight.indexOf(min)

          return index

        }

        function setPosition() {

          var colNum = 3

          var appWidth = $('#app').width() - (colNum - 1) * 20 //20是没个img之间的margin

          var itemWidth = parseInt(appWidth / colNum)

          $('.item').width(itemWidth)

          var columTotalHeight = new Array(colNum).fill(0)

          var top = 0

          var left = 0

          for (var i = 0; i < $('.item').length; i++) {

            let current = getMinIndex(columTotalHeight)

            left = current * itemWidth + current * 20

            top = columTotalHeight[current]

            $('.item')

              .eq(i)

              .css({

                left: left + 'px',

                top: top + 'px'

              })

            let currentImgHeight = $('.item img')

              .eq(i)

              .height()

            columTotalHeight[current] =

              columTotalHeight[current] + currentImgHeight + 20

            $('#app').height(Math.max.apply(null, columTotalHeight) + 100)

            $('.item')

              .eq(i)

              .height(currentImgHeight)

          }

        }

        setPosition()

        window.onresize = function() {

          setPosition()

        }

      })

    </script>

  </body>

</html>

二:动态添加元素

(需要后台配合,图片地址带上图片的大小) 拿到图片的地址,图片的地址包含图片的大小。可以获取图片的高度,从而计算列高度差。创建img标签,拼接到页面上。

效果图:


代码如下:

<!DOCTYPE html>

<html>

  <head>

    <meta charset="utf-8" />

    <meta name="viewport" content="width=device-width,initial-scale=1.0" />

    <title>ttt</title>

    <style>

      * {

        margin: 0;

        padding: 0;

        border: 0;

      }

      #app {

        border: 1px solid #000;

        box-sizing: content-box;

        margin: 0 auto;

        position: relative;

        font-size: 0;

      }

      .item {

        box-sizing: border-box;

        height: auto;

        display: inline-block;

        width: 200px;

        vertical-align: text-top;

        margin: 5px;

      }

      .item > img {

        display: block;

        margin-bottom: 5px;

      }

    </style>

    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.5/TweenLite.min.js"></script>

    <script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script> -->

    <script

      type="text/javascript"

      src="http://ajax.googleapis.com/ajax/libs

/jquery/1.4.0/jquery.min.js"

    ></script>

  </head>

  <body>

    <div id="app"></div>

    <script>

      $(document).ready(function() {

        //获取高度最小的列

        function getMinIndex(columTotalHeight) {

          let min = Math.min.apply(null, columTotalHeight)

          let index = columTotalHeight.indexOf(min)

          return index

        }

        const imgResource = [

          'http://localhost:4000/dangao.jpg?200*150',

          'http://localhost:4000/male.png?200*200',

          'http://localhost:4000/dangao.jpg?200*150',

          'http://localhost:4000/dangao.jpg?200*150',

          'http://localhost:4000/male.png?200*200',

          'http://localhost:4000/male.png?200*200'

        ]

        //获取图片的高度

        function getImgHeight(imgsrc) {

          let height = parseInt(

            imgsrc

              .split('?')

              .pop()

              .split('*')

              .pop()

          )

          return height

        }

        //动态设置容器的高度,不够一列的宽度设置为容器的margin

        function autoLayout() {

          var windowWidth = document.body.clientWidth

          var resetWidth = windowWidth % 210 //图片的宽度是200 210 时带上左右margin

          $('#app').width(windowWidth - resetWidth)

          var columns = parseInt(windowWidth / 210)

          for (var j = 0; j < columns; j++) {

            var div = document.createElement('div')

            div.setAttribute('class', 'item')

            $('#app').append(div)

          }

          return columns

        }

        function setPosition() {

          //返回可以容纳的列数

          var colNum = autoLayout()

          var columTotalHeight = new Array(colNum).fill(0)

          for (var i = 0; i < imgResource.length; i++) {

            let currentBox = getMinIndex(columTotalHeight)

            var img = document.createElement('img')

            img.src = imgResource[i]

            img.style.border = '1px solid #000'

            var currentImgHeight = getImgHeight(imgResource[i])

            columTotalHeight[currentBox] =

              columTotalHeight[currentBox] + currentImgHeight + 5

            $('.item')

              .eq(currentBox)

              .append(img)

          }

          for (var j = 0; j < $('.item').length; j++) {

            $('.item')

              .eq(j)

              .height(columTotalHeight[j])

          }

        }

        setPosition()

        window.onresize = function() {

          setPosition()

        }

      })

    </script>

    <!-- built files will be auto injected -->

  </body>

</html>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。