Jquery实现瀑布流布局

    技术2024-07-09  77

    瀑布流布局

    什么是瀑布流?用JavaScript怎么实现?一些疑惑点

    什么是瀑布流?

    一种图片在网页的布局方式,具体要求为:从页面第二行开始,后续图片跟在页面中最矮的那张图片后面

    用JavaScript怎么实现?

    具体实现如下所示

    /*HTML部分*/ <head> <link rel="stylesheet" href="main.css"> </head> <div id="box"></div>//container和img由js动态加入 <script src="jquery.min.js"></script> <script src="loadFile.js"></script> <script src="main.js"></script> /*CSS部分*/ /*首先清空默认样式*/ #box{ position: relative; } .container{ float: left; } .container>.pic{ width: 200px; } .container>.pic>img{ width: 100%; } /*JS部分*/ /*loadFile.js(在window.onload之前执行,加载DOM树)*/ $(function () { function addImg(imgNum,eleID) { let container for (let i = 1; i < imgNum; i++) { container=$("<div class='container'><div class='pic'><img src='images/"+i+".jpg' alt=''></div></div>") $(eleID).append(container) } } addImg(109,"#box"); }) /*******************************************/ /*main.js(在$(function(){})之前执行,DOM树加载完毕 )*/ window.onload=function () { let waterFall=function (eleID) { let boxWidth = 0, colo = 0, $egEle = $(eleID).children().eq(0), boxArr = [], heightArr = [], minHeight = 0,minHeightInd = 0 /*1.父盒子居中*/ /*1.1盒子宽度*/ boxWidth = $egEle.outerWidth() /*1.2列数*/ colo = parseInt($(window).width() / boxWidth) /*1.3实现居中*/ $(eleID).css({ // width: boxWidth * colo + "px", margin: "0 auto" }) /*2.定位盒子*/ /*2.1找出第一行盒子最矮的一个*/ /*2.1.1 第一行盒子高度数列*/ boxArr = $egEle.prevObject // console.log(boxArr); for (let i = 0; i < boxArr.length; i++) { if (i < colo) {//第一行盒子 heightArr.push(boxArr.eq(i).outerHeight()) } else { /*2.1.2 盒子中最矮的一个值及索引*/ minHeight = Math.min.apply(null, heightArr) minHeightInd = heightArr.indexOf(minHeight) /*2.2定位后续盒子*/ boxArr.eq(i).css({ position: "absolute", top: minHeight + "px", left: boxWidth * minHeightInd + "px" }) /*2.3 高度数列更新*/ heightArr[minHeightInd] += boxArr.eq(i).outerHeight() } } } /*执行*/ waterFall("#box"); }

    一些疑惑点

    container之间无任何外边距,照片之间间距是由container的内边距造成的

    用js加载图片文件后,获取元素高度出现了异常(所有盒子高度为一个奇怪的值),是因为$(function(){})与 window.onload=function(){}的区别造成的,之前将文件的加载和后续样式的更改js全部写到了$(function(){})中,后面将loadFile.js写到$(function(){}),将main.js写到window.onload=function(){}就解决了

    $(function(){})与window.οnlοad=function(){}的区别

    $(function(){})就是$(document).ready=function(){},是在加载DOM树的时候执行window.onload=function(){}则是在DOM树加载完成之后才执行$(function(){})比window.onload=function(){}先执行

    3.为了代码的易用性以及可维护性,将父盒子#box的居中用js动态来完成

    对于块级元素来说,居中使用到的是margin:0 auto,但前提是块级元素必须要有宽度,而这个块级元素#box的宽度是动态的,Width = boxWidth * colo,即宽度为container宽度乘以列数, colo = parseInt($(window).width() / boxWidth),

    4.除第一行的盒子之外,后续盒子全部用绝对定位来排列

    4.1 怎么确定盒子在第一行?

    拿到盒子数列boxArr!

    利用到jQuery中的prevObject属性,

    jquery选择器在遍历的过程中都会找到一组元素(一个jQuery对象),然后jQuery会把这组元素推入到栈中,prevObject属性就指向这个对象栈中的前一个对象,通过这个属性就可以回溯到最初的DOM元素集,减少重复的查找和遍历操作

    ​然后遍历boxArr,如果索引小于列数,即index < colo,则这些元素都属于第一行

    4.2 后续盒子定位? 拿到第一行盒子的高度数列组heightArr 第一行之后的第一个盒子定位在heightArr中的最小值盒子之后

    heightArr最小值? Math.min.apply(null,heightArr) ,

    5.heightArr最小高度的更新☆ heightArr[minHeightInd] += boxArr.eq(i).outerHeight()

    Processed: 0.013, SQL: 9