瀑布流布局

作者: 海山城 | 来源:发表于2017-10-20 13:47 被阅读45次

    什么是瀑布流布局?

    先来看个瀑布流布局的网站实例
    瀑布流布局
    从上面的网站中可以看出,瀑布流布局就是这种错落式的布局方式。它有一个特点,整个布局以列为单位,下一个区块总是放在总高度最短的那一列的下面。

    实现

    整体思路:通过js找出一行中高度最短的那列,然后通过绝对定位将区块放在那列的下方
    step1

    • 先显示很多不同高度的img,宽度可以不同,反正到时候都是设置成统一宽度的
    • http://via.placeholder.com/100x100接口可以用来模拟一张图片,100x100即图片的宽和高,通过设置不同的高度获取到很多图片
      正常连续多张图片的显示

    step2

    • 将图片的position设置成absolute
    .waterfall{
      position: relative;
    }
    .waterfall img{
      width: 100px;
      margin: 10px;
      position: absolute;
      
    }
    
    • 编写js控制图片位置
    //获取图片的宽度
    var imgWidth = $('.waterfall img').outerWidth(true)
    //列数 = 外层容器宽度 / 图片宽度
    var colCnt = Math.floor($('.waterfall').width() / imgWidth)
    //定义一个存放每列列高的数组
    var colHeight = []
    //根据列数初始化数组
    for(var i=0; i<colCnt; i++){
      colHeight[i] = 0
    }
    //获取数组中最小值下标
    var minIndex = colHeight.indexOf(Math.min.apply(null, colHeight))
    //对于每个img找到数组中列高最小的位置进行绝对定位
    $('.waterfall img').each(function(){
      $(this).css({
        left: minIndex * imgWidth,
        top: colHeight[minIndex]
      })
      colHeight[minIndex] += $(this).outerHeight(true)
      minIndex = colHeight.indexOf(Math.min.apply(null, colHeight))
    })
    

    注:
    ① outerWidth()方法返回第一个匹配元素的外部宽度,该方法包含padding和border
    如需包含margin,使用outerWidth(true),这样在css中设置的图片的margin会被计算在内,从而显示有间隔的效果。

    整体效果

    step3
    step2已经实现了瀑布流布局,可是还是不够完善,变动页面的宽度,瀑布流布局并不能跟着变化,相当于根据初始页面的宽度进行了一次性布局。下面增加实现瀑布流布局跟着宽度变化
    js代码改成如下

    //获取图片宽度
    var imgWidth = $('.waterfall img').outerWidth(true)
    //列数 = 外层容器宽度 / 图片宽度
    var colCnt = Math.floor($('.waterfall').width() / imgWidth)
    //定义一个存放每列列高的数组
    var colHeight = []
    
    function waterfall(colCount){
      //根据列数初始化数组
      for(var i=0; i<colCount; i++){
        colHeight[i] = 0
      }
      //获取数组中最小值下标
      var minIndex = colHeight.indexOf(Math.min.apply(null, colHeight))
      //对于每个img找到数组中列高最小的位置进行绝对定位
      $('.waterfall img').each(function(){
        $(this).css({
          left: minIndex * imgWidth,
          top: colHeight[minIndex]
        })
        colHeight[minIndex] += $(this).outerHeight(true)
        console.log('colHeight', colHeight)
        minIndex = colHeight.indexOf(Math.min.apply(null, colHeight))
        console.log('minIndex',minIndex)
      })
    }
    //首次布局等到图片到来在执行
    $('.waterfall img').on('load', function(){
      waterfall(colCnt)
    })
    //resize页面重新布局
    $(window).on('resize', function(){
      imgWidth = $('.waterfall img').outerWidth(true)
      colCnt = Math.floor($('.waterfall').width() / imgWidth)
      waterfall(colCnt)
    })
    

    注:在img的css中加入transition可以实现resize页面瀑布流布局变化的动画效果

    最终效果
    最终页面展示

    相关文章

      网友评论

        本文标题:瀑布流布局

        本文链接:https://www.haomeiwen.com/subject/mlimuxtx.html