美文网首页经典布局
瀑布流布局&木桶布局

瀑布流布局&木桶布局

作者: 婷楼沐熙 | 来源:发表于2017-02-20 16:04 被阅读449次

    一、实现一个瀑布流布局效果。

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>瀑布流布局</title>
      <style>
        *{
          margin: 0px;
          padding: 0px;
        }
        .waterfall{
          position: relative;
        }
        .item{
          width: 200px;
          position: absolute;
          transition: all .6s;
          margin: 10px;
          color: #383A3F;
          text-align: center;
          font-weight: 600;
        }
        .h1{
          line-height: 200px;
          background: #9DC8C8;
        }
        .h2{
          line-height: 380px;
          background: #D499B9;
        }
        .h3{
          line-height: 250px;
          background: #D7FFF1;
        }
        .h4{
          line-height: 320px;
          background: #F6B352;
        }
        .h5{
          line-height: 450px;
          background: #E71D36;
        }
      </style>
    </head>
    <body>
      <div class="waterfall">
        <div class="item h1">
            1
        </div>
        <div class="item h2">
            2
        </div>
        <div class="item h1">
            3
        </div>
        <div class="item h4">
            4
        </div>
        <div class="item h2">
            5
        </div>
        <div class="item h1">
            6
        </div>
        <div class="item h3">
            7
        </div>
        <div class="item h5">
            8
        </div>
        <div class="item h3">
            9
        </div>
        <div class="item h1">
            10
        </div>
        <div class="item h2">
            11
        </div>
        <div class="item h4">
            12
        </div>
        <div class="item h5">
            13
        </div>
        <div class="item h1">
            14
        </div>
        <div class="item h3">
            15
        </div>
        <div class="item h1">
            16
        </div>
        <div class="item h2">
            17
        </div>
        <div class="item h4">
            18
        </div>
        <div class="item h5">
            19
        </div>
        <div class="item h1">
            20
        </div>
        <div class="item h3">
            21
        </div>
        <div class="item h2">
            22
        </div>
        <div class="item h4">
            23
        </div>
        <div class="item h5">
            24
        </div>
        <div class="item h2">
            25
        </div>
      </div>
    
      <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
      <script>
        var Waterfall = {
          arrHeight: [],
          init: function($container) {
            this.$ct = $container;
            this.$items = this.$ct.find('.item');
            this.itemsWidth = this.$items.first().width();
            this.bind();
            this.render();
          },
          bind: function() {
            let that = this;
            $(window).on('resize', function() {
              that.render();
            })
          },
          render: function() {
            let that = this;
            this.arrInit(this.colNum());
            this.$items.each(function() {
              that.placeItem($(this));
            })
          },
          colNum: function() {
            return Math.floor(this.$ct.width() / this.itemsWidth);
          },
          arrInit: function(colNum) {
            for(let i=0; i<colNum; i++) {
              this.arrHeight[i] = 0;
              console.log(this.arrHeight);
            }
          },
          placeItem: function($el) {
            // 1. 找到arrColHeight的最小值,得到是第几列
                  // 2. 元素left的值是 列数*宽度
                  // 3. 元素top的值是 最小值
                  // 4. 放置元素的位置,把arrColHeight对应的列数的值加上当前元素的高度
            let minHeightInfo = this.getIndexOfMinHeight(this.arrHeight),
                min = minHeightInfo.min,
                idx = minHeightInfo.idx;
            $el.css({
              left: idx*this.itemsWidth,
              top: min
            });
            this.arrHeight[idx] += $el.outerHeight(true);
          },
          getIndexOfMinHeight: function(arr) {
            console.log(arr);
            let min = arr[0],
                idx = 0;
            for(let i = 1; i< arr.length; i++) {
              if(arr[i] < min) {
                min = arr[i];
                idx = i;
              }
            };
            return {min: min, idx: idx};
          }
        }
    
        Waterfall.init($('.waterfall'));
      </script>
    </body>
    </html>
    

    二、实现木桶布局效果。

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>木桶布局</title>
      <style>
        *{
          margin: 0;
          padding: 0;
        }
        body{
          background: #f1bbba;
        }
        .barrels{
          width: 1000px;
          margin: 20px auto 0 auto;
        }
        .img-row:after{
          content:"";
          display:block;
          clear:both;
        }
        .img-ct{
          float:left;
        }
        .load{
          visibility: hidden;
          height: 20px;
        }
      </style>
    </head>
    <body>
      <div class="barrels">
    
      </div>
      <div class="load">我出现就加载</div>
    
      <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
      <script>
        var barrels = {
          imgNum: 0,
          standardHeight: 0,
          rowList: [],
          barrelsWidth: 0,
    
          init: function($barrels, imgNum, standardHeight) {
            this.$barrels = $barrels;
            this.imgNum = imgNum;
            this.standardHeight = standardHeight;
            this.barrelsWidth = this.$barrels.width();
            this.loadImg();
          },
    
          render: function(imgInfo) {
            let that = this,
                barrelsWidth = this.barrelsWidth,
                // rowList = this.rowList,
                rowWidth = 0,
                newImgHeight = 0,
                lastImgInfo = imgInfo;
    
            that.rowList.push(lastImgInfo); // 当这行图片没有超过容器宽度时,则一直放到这一行。
            $.each(that.rowList, function(index, imgInfo) {
              rowWidth += imgInfo.width;
              if(rowWidth > barrelsWidth) {
                that.rowList.pop();
                rowWidth -= imgInfo.width;
                // 重新计算缩放比例
                newImgHeight = that.standardHeight * barrelsWidth / rowWidth;
                that.appendHtml(newImgHeight);
                that.rowList = [];
                that.rowList.push(lastImgInfo);
              }
            })
          },
    
          appendHtml: function(newHeight) {
            let $newRow = $('<div class="img-row"></div>'); // 创建新元素
            $.each(this.rowList, function(index, imgInfo) {
              let $newImgCt = $('<div class="img-ct"></div>'),
                  $newImg = imgInfo.targetImg;
              $newImg.height(newHeight);
              $newImgCt.append($newImg);
              $newRow.append($newImgCt);
            })
            this.$barrels.append($newRow);
          },
    
          loadImg: function() {
            let that = this;
            let imgURLs = this.getURL(this.imgNum);
            $.each(imgURLs, function(index, url) {
              let img = new Image();
              img.src = url;
              img.onload = function() {
                let originWidth = img.width,
                    originHeight = img.height,
                    ratio = originWidth/originHeight;  // 宽度根据比例进行缩放
                let imgInfo = {
                  targetImg: $(img),
                  width: that.standardHeight*ratio,
                  height: that.standardHeight
                }
                that.render(imgInfo);
              };
    
            })
          },
    
          getURL: function(imgNum) {
            let width, height, color;
            let urls = [];
            for(let i = 0; i < imgNum;i++) {
              width = Math.floor(Math.random() * 100 + 200);
              height = Math.floor(Math.random() * 100 + 200);
              color = Math.random().toString(16).substring(2,8);
              // urls.push("http://placehold.it/" + width + "x" + height + "/" + color + "/fff");
              urls.push("https://unsplash.it/" + width + "/" + height + "/?random");
            }
            return urls;
          },
    
          // 判断.load是否出现
          isVisible: function($node) {
            var windowHeight = $(window).height(),
                  scrollTop = $(window).scrollTop(),
                  offsetTop = $node.offset().top,
                  nodeHeight = $node.outerHeight(true);
            if (windowHeight + scrollTop > offsetTop && scrollTop < offsetTop + nodeHeight) {
                return true;
            }else{
                return false;
            }
          }
        }
    
        // 一开始的时候让图片铺满屏幕
        barrels.init($('.barrels'), 20, 200);
    
        var clock;
        $(window).on('scroll',function () {
          if (clock) {
            clearTimeout(clock);
          }
          clock = setTimeout(function () {
            if(barrels.isVisible($('.load'))) {
              barrels.init($('.barrels'), 30, 200);
            }
          },200);
        });
      </script>
    </body>
    </html>
    

    预览

    三、实现一个新闻瀑布流新闻网站。查看效果

    jsonp 接口参数: http://platform.sina.com.cn/slide/album_tech?jsoncallback=func&app_key=1271687855&num=3&page=4
    代码
    预览

    相关文章

      网友评论

        本文标题:瀑布流布局&木桶布局

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