Diseño de flujo en cascada del bloque div front-end

prefacio

Como se muestra en la figura, cada categoría es un bloque. El número de categorías es dinámico, y el número de elementos en cada categoría es dinámico.El administrador de productos requiere un diseño en cascada como el de la figura. Aprenda del diseño de flujo de cascada de las imágenes de otras personas para realizar el diseño de flujo de cascada de este bloque div.
inserte la descripción de la imagen aquí

comenzar

Para el diseño en cascada de las imágenes, hay un ancho fijo o una altura fija. Elijo el método de ancho fijo. Pero en realidad, los navegadores tienen múltiples anchos de pantalla y es necesario establecer el ancho de cada bloque div y ser adaptable.
Así que aquí,
1. Uso css para calcular y configurar el ancho del bloque div en diferentes pantallas: si el ancho es> 1500, se pueden colocar 5 columnas y se elimina el ancho de cada columna, es decir, 2. Establecer width:calc(100% - 30px*4)/5;cada width:calc(20% - 24px);
bloque div está absolutamente posicionado.
3. Use js para calcular la posición de posicionamiento de cada bloque div: los bloques div en la primera fila están ordenados secuencialmente, a partir de la segunda fila, encuentre la columna con la altura más pequeña cada vez, llénela y luego vuelva a calcular la columna con la altura más pequeña, y llenarlo a su vez.
4. Debido al posicionamiento absoluto del bloque div, la altura de su elemento principal colapsa. Use js para tomar la última columna más alta y establecer la altura del elemento principal.

código superior

html

<ul :style="{height:ulHeight+'px'}" ref="content">
	<li v-for="(item,index) in blockList" 
	    :style="{left:item.left+'px',top:item.top+'px',height:item.height+'px'}" 
	     v-if="item.serviceData.length>0">
			<p>{
   
   {item.typeName}}</p>
			<div class="knowledgeContent">
				<div class="knowledgeItem" 
					 v-for="item1 in item.serviceData" 
					 @click="checkDetail(item,item1)">
						 <i class="itemPoint"></i>
						 <span>{
   
   {item1.title}}</span>	
				</div>
			</div>
	</li>
</ul>

CSS

ul{
    
    
		position: relative;
		li{
    
    
			width: calc(20% - 24px);
			border: 1px solid #DBDBFD;
			box-shadow: 0 2px 4px 2px #EBEBEB;
			padding-bottom: 10px;
			position: absolute;
			p{
    
    
				height: 50px;
				line-height: 50px;
				padding: 0 15px;
				background: url(../../../assets/img/csManager/knowledgeItemBg.png) ;
				font-family: PingFangSC-Medium;
				font-size: 14px;
				color: #000000;
			}
			.knowledgeContent{
    
    
				.knowledgeItem{
    
    					
					padding: 10px;
					cursor: pointer;
					i{
    
    
						display: inline-block;
						width: 6px;height: 6px;
						border-radius: 50%;
						background: #A7A6DA;
						margin-right: 8px;
						vertical-align: top;
						margin-top: 7px;
						margin-right: 10px;
					}
					span{
    
    
						display: inline-block;
						vertical-align: top;
						width: calc(100% - 25px);
						font-size: 14px;
						color: #000;
					}
					&:hover{
    
    
						i{
    
    
							background: #302e77;
						}
						span{
    
    
							color: #302E77;
						}
					}
				}
			}
		}
	}
@media screen and(max-width:1500px){
    
    
		ul {
    
    
			li{
    
    
				width: calc(25% - 22.5px);
			}
		}
}

javascript

export default {
    
    
	data () {
    
    
		return {
    
    
			colNumbers:0,//列数
			colWidth:0,//块宽度
			colHeight:[],//块高度数据列表,用来查找最小高度,从而实现瀑布流算法
			ulHeight:0,//ul高度(因子元素绝对定位,父元素高度塌陷,故取colHeight最大值加内边距10)
			list:[
				{
    
    typeName:'类别1',
				 seviceData:[{
    
    id:1,title:'标题1'}]
				 }
			],
			blockList:[],//含有定位位置的列表,用来循环显示
		}
	},
	methods:{
    
    
		//计算块列数,>1500时为5列,<=1500 时,为4列,间距为30
		getColNumbers() {
    
    
			let screenwidth = document.documentElement.clientWidth;
			if(screenwidth>1500){
    
    
				this.colNumbers = 5;
				this.colWidth = (this.$refs.content.clientWidth - 30*4)/5;
			}else{
    
    
				this.colNumbers = 4;
				this.colWidth = (this.$refs.content.clientWidth - 30*3)/4;
			}			
		},
		//读取块,设置高度信息
		loadBlock() {
    
    
			this.getColNumbers();
			for(let i =0; i < this.list.length; i++){
    
    
				//1.求本块高度
				let height = 80;
				this.list[i].serviceData.forEach(item=>{
    
    
					if(item.title.length>15){
    
    //标题超过15字,换行,此条高度为62px(标题限制为20字)
						height+=62;
					}else{
    
    
						height+=41;
					}
				})
				//2.传参调用方法
				this.render({
    
    
					index:i,
					height:height,
					...this.list[i]
				})
			}
			//3.因子元素全部绝对定位,父元素高度用js计算得到,取高度最大值
			this.ulHeight =  Math.max.apply(null, this.colHeight);
		},
		//设置渲染块的list
		render(blockInfo){
    
    
			let colIndex = blockInfo.index % this.colNumbers;		
			
			if (blockInfo.index < this.colNumbers) {
    
    //首行:top为 0,记录每列的高度
				blockInfo.top = 0
				this.colHeight[colIndex] = blockInfo.height;
				blockInfo.left = colIndex == 0? colIndex * this.colWidth :(colIndex * this.colWidth+30*colIndex) ;
			} else {
    
    
				//获取高度的最小值
				let minHeight = Math.min.apply(null, this.colHeight)
				let minIndex = this.colHeight.indexOf(minHeight)
				//此块的 top 为上面块的高度,left 相等
				blockInfo.top = minHeight + 30;
				let minColIndex = minIndex % this.colNumbers;//计算最小的在哪一列
				blockInfo.left = minColIndex == 0? minColIndex * this.colWidth :(minColIndex * this.colWidth+30*minColIndex) ;
				//把高度加上去
				this.colHeight[minIndex] +=  30+blockInfo.height;
			}
			this.blockList.push(blockInfo)
			
		}
	}

Finalizar

Registre el problema aquí, si hay alguna necesidad de modificar, hágamelo saber. Referencia del artículo: 5 formas de realizar el diseño del flujo de la cascada con usted

Supongo que te gusta

Origin blog.csdn.net/qq_39352780/article/details/118155077
Recomendado
Clasificación