美文网首页
JavaScript瀑布流

JavaScript瀑布流

作者: F_er | 来源:发表于2020-07-03 15:09 被阅读0次

    什么是瀑布流?

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

    瀑布流布局

    用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");
    }
    

    一些疑惑点

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

    2. 用js加载图片文件后,获取元素高度出现了异常(所有盒子高度为一个奇怪的值),是因为$(function(){})window.onload=function(){}的区别造成的

      之前将文件的加载和后续样式的更改js全部写到了$(function(){})

      后面将loadFile.js写到$(function(){}),将main.js写到window.onload=function(){}就解决了

    $(function(){})window.onload=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()

    相关文章

      网友评论

          本文标题:JavaScript瀑布流

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