• css布局-瀑布流的实现


    一、基本思路

    1、先看最终的效果图:

    2、实现原理:通过position:absolute(绝对定位)来定位每一个元素的位置,并且将当前列的高度记录下来方便下一个dom位置的计算

    二、代码实现

    1、版本一:根据思路实现基础版

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>css布局-瀑布流的实现</title>
    <style type="text/css">
    .box {
      position: relative;
    	 500px;
    	min-height: 100px;
    	margin: 100px auto;
    	background: #eeeeee;
    }
    .item {
      position: absolute;
       120px;
      left: 0;
      top: 0;
    }
    </style>
    </head>
    <body>
    <div class="box">
        <div class="item" style="height: 40px;background: red;"></div>
        <div class="item" style="height: 50px;background: blue;"></div>
        <div class="item" style="height: 100px;background: green;"></div>
        <div class="item" style="height: 60px;background: gray;"></div>
        <div class="item" style="height: 50px;background: orange;"></div>
        <div class="item" style="height: 20px;background: yellow;"></div>
        <div class="item" style="height: 40px;background: red;"></div>
        <div class="item" style="height: 50px;background: blue;"></div>
        <div class="item" style="height: 100px;background: green;"></div>
        <div class="item" style="height: 120px;background: gray;"></div>
        <div class="item" style="height: 58px;background: orange;"></div>
        <div class="item" style="height: 36px;background: yellow;"></div>
    </div>
    <script type="text/javascript">
      const BOX_WIDTH = document.querySelector('.box').offsetWidth //瀑布流外层盒子的宽度
      const ITEM_WIDTH = document.querySelector('.item').offsetWidth //瀑布流内层盒子的宽度
      const COLUMN = Math.floor(BOX_WIDTH/ITEM_WIDTH)   //根据宽度计算可渲染的列数
      const MARGIN = (BOX_WIDTH - ITEM_WIDTH*COLUMN)/(COLUMN-1) // 根据宽度计算每一列的间距
      const MARGINTOP = 10 //固定设置每一个小盒子上下间距是10
      let height_arr = new Array(COLUMN).fill(0)  //定义一个长度等同与列数的数组用来存储每一列的高度,初始值均为0
      let item = document.querySelectorAll('.item')
    //遍历每一个小盒子,确定小盒子的位置 for(let i = 0; i < item.length; i++) { let index = height_arr.indexOf(Math.min.apply(null, height_arr)) item[i].style.left = (ITEM_WIDTH + MARGIN) * index + 'px' item[i].style.top = height_arr[index] + MARGINTOP + 'px' height_arr[index] += item[i].offsetHeight + MARGINTOP }
    //将数组中最大的值,即最高的那一列的高度赋给外层盒子 document.querySelector('.box').style.height = Math.max.apply(null, height_arr) + 'px' </script> </body> </html>

    2、版本二:对版本一进行封装,方便重复使用

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>css布局-瀑布流的实现</title>
    <style type="text/css">
    .box {
      position: relative;
    	 500px;
    	min-height: 100px;
    	margin: 100px auto;
    	background: #eeeeee;
    }
    .item {
      position: absolute;
       120px;
      left: 0;
      top: 0;
    }
    </style>
    </head>
    <body>
    <div class="box" style="">
        <div class="item" style="height: 40px;background: red;"></div>
        <div class="item" style="height: 50px;background: blue;"></div>
        <div class="item" style="height: 100px;background: green;"></div>
        <div class="item" style="height: 60px;background: gray;"></div>
        <div class="item" style="height: 50px;background: orange;"></div>
        <div class="item" style="height: 20px;background: yellow;"></div>
       <div class="item" style="height: 40px;background: red;"></div>
       <div class="item" style="height: 50px;background: blue;"></div>
       <div class="item" style="height: 100px;background: green;"></div>
       <div class="item" style="height: 120px;background: gray;"></div>
       <div class="item" style="height: 58px;background: orange;"></div>
       <div class="item" style="height: 36px;background: yellow;"></div>
    </div>
    <script type="text/javascript">
    	function WaterFall(params) {
    		this.box = (params && params.parent) || '.box'
    		this.item = (params && params.child) || '.item'
    		this.column = (params && params.column) || 0
    		this.row_margin = (params && params.row_margin) || 0
    		this.column_margin = (params && params.column_margin) || 10
    		this.height_arr = []
    		this._box_width = 0
    		this._item_width = 0
    		this._computed = function() {
    			this._box_width = document.querySelector(this.box).offsetWidth
    			this._item_width = document.querySelector(this.item).offsetWidth
    			this.column = Math.floor((this._box_width - this.row_margin)/this._item_width) //列数
    			this.row_margin = !this.row_margin ? (this._box_width - this._item_width * this.column)/(this.column-1) : this.row_margin
    		}
    		this.init = function() {
    			this._computed()
    			let item = document.querySelectorAll(this.item)
    			this.height_arr = new Array(this.column).fill(0)
    			for(let i = 0; i < item.length; i++) {
    				let index = this.height_arr.indexOf(Math.min.apply(null, this.height_arr))
    				item[i].style.left = (this._item_width + this.row_margin) * index + 'px'
    				item[i].style.top = this.height_arr[index] + this.column_margin + 'px'
    				this.height_arr[index] += item[i].offsetHeight + this.column_margin
    			}
    			document.querySelector('.box').style.height = Math.max.apply(null, this.height_arr) + 'px'
    		}
    	}
    	var test = new WaterFall()
    	test.init()
    </script>
    </body>
    </html>
    

    三、总结:瀑布流的实现并不复杂,只要清楚了原理剩下的就是耐心的计算间距以及小盒子的位置啦~

  • 相关阅读:
    其他
    聚类算法:ISODATA算法
    大神博客
    Fiddldr 教程之:HTTP协议详解(转)
    设计模式之装饰模式的复习
    NOIP 2011 聪明的质监员
    CSP-S2020/NOIP2020模板总结(Updating)
    CSP-S2020/NOIP2020复习指南
    洛谷 U137412 高斯的小宇宙
    NOIP2020模板测试题大全
  • 原文地址:https://www.cnblogs.com/zhiying/p/11046887.html
Copyright © 2020-2023  润新知