web前端原生js实现瀑布流

JavaScript023

web前端原生js实现瀑布流,第1张

思路分析

步骤一:构建成行元素 + 寻找新增元素追加位置

瀑布流所有元素的宽度是固定的,我们用浏览器的宽度除以每个瀑布流块的宽度,就是每一行可容纳的瀑布流块的个数.因为,每个瀑布流块的高度不一,我们姑且把组成一行的这组元素称为成行元素,在成行元素放置完毕后,我们如果要再增加一个元素,那么它的位置应该这样找?

“获取成行元素集合中高度最低的那个元素,待放置的元素的top值应该是这个最低元素的高,left值应该是这个最低元素的left值”

这样,新增的这一个元素我们就找到了它存放的位置.这样成行元素中的最低高度值就变为了原来的高度+新增元素的高度.

步骤二:重复步骤一,依赖成行元素追加新元素

步骤一中我们已经实现了一次成行元素追加一个新的元素,这样新元素增加之后我们就构建了新的成行元素,之后的操作就是在新的成行元素中追加新元素,原理同步骤一.

<!doctype html>

    <meta charset="UTF-8">

    <title>瀑布流效果实现

    <script type="text/javascript" src="scripts/jquery-1.8.2.min.js">

    <script type="text/javascript" src="scripts/jquery.easydrag.handler.beta2.js">

    <script type="text/javascript">

      window.onload=function(){

//获取父级对象

        var oParent = document.getElementById("main")

        //获取父级[第一个参数]下的所有的子元素[按照第二个参数匹配]

        var aPin =getClassObject(oParent,"pin")

        //获取每一个块的宽度

        var iPinW = aPin[0].offsetWidth

        // //计算每行放多少个pin(瀑布流块)页面的宽度/每一个瀑布流块的宽度

        var num = Math.floor(document.documentElement.clientWidth/iPinW)

        //重置父级的样式,这样保证图片整体居中

        oParent.style.cssText="width:" + num*iPinW +"pxmargin:0 auto"

        var compareArray = []

        //遍历获取到的所有瀑布流块

        for (var i =0i

if(i

//成行元素

            compareArray[i] = aPin[i].offsetHeight

          }else{

//获取成行元素中高度最低的值

            var minHeight = Math.min.apply('',compareArray)

            //alert(compareArray + ",min=" + minHeight)

//获取成行元素中高度最低元素的索引

            var minHkey =getMinHeightKey(compareArray,minHeight)

            //为新增的瀑布流块设置定位

            aPin[i].style.position ="absolute"

            aPin[i].style.top = minHeight +"px"

            //设定新增加的瀑布流块的top和left

            aPin[i].style.left =aPin[minHkey].offsetLeft +"px"

            //将该索引位置的高度改变为新增后的高度[原来瀑布流块的高度+新增的瀑布流块的高度]

            compareArray[minHkey] += aPin[i].offsetHeight

          }

}

}

/**

*    获取parent下所有样式名为className的对象集合

*/

      function getClassObject(parent,className){

var obj = parent.getElementsByTagName("*")

        var result = []

        for(var i=0i

//变量如果匹配className,将匹配的对象放入数组

          if(obj[i].className==className){

result.push(obj[i])

          }

}

return result

      }

/**

*    获取arr数组中值为minH的值在数组中的索引

*/

      function getMinHeightKey(arr,minH){

for(key in arr){

if(arr[key] == minH){

return key

          }

}

}

    <style type="text/css">

        /*设置每一个瀑布流块*/

        #main .pin{

width:220px

            height:auto

            padding:15px 0px 0px 15px/*上 右 下 左*/

            float:left

        }

/*设置每一个瀑布流块中的图像样式*/

        #main .pin .box{

width:200px

            height:auto

            padding:10px

            background:#FFF

            border:1px solid #ccc

            box-shadow:0px 0px 6px #ccc/*中间投影*/

            border-radius:5px/*圆角*/

        }

#main .pin .box img{

width:200px

        }

<div id="main">

    <div class="pin">

        <div class="box">

            <img src="images/1.webp">

    <div class="pin">

        <div class="box">

            <img src="images/2.webp">

    <div class="pin">

        <div class="box">

            <img src="images/3.webp">

    <div class="pin">

        <div class="box">

            <img src="images/4.webp">

    <div class="pin">

        <div class="box">

            <img src="images/5.webp">

    <div class="pin">

        <div class="box">

            <img src="images/6.webp">

    <div class="pin">

        <div class="box">

            <img src="images/7.webp">

</html>

瀑布流布局,一般指根据内容高度自适应填充到某一列以使整体页面和谐,常见的有图片网站,比如每一行每一列的内容是错开的。

瀑布流布局一般是下面这个样子

css中有这么两个属性:

注意

这也是我推荐大家用第一种方法的最主要原因。

这种方案做出来的效果有点奇葩,特殊的应用场景可能会用到,最终效果是横向瀑布流

flex布局中有一个属性 flex-flow ,指明在哪个方向上在长度不够的情况想拆行,详情大家自己查阅

第一种方法其实是最合适的,也是对开发人员要求最高的,即使有思路与算法在开发过程中也会踩很多坑,比如(1)图片预加载,(2)querySelector取元素居然获取不到,(3)使用box-sizing简化计算过程降低复杂性,等等。 box-sizing 属性用好了非常高效,推荐大家去仔细看看

第二种方法其实也可行,但是不推荐

第三种方法就有点扯了,估计不常用到,大家看看就行

在网页中实现瀑布流效果方法:

1.传统多列浮动

各列固定宽度,并且左浮动

一列中的数据块为一组,列中的每个数据块依次排列即可

更多数据加载时,需要分别插入到不同的列上。

2. CSS3 定义

由 chrome/ff 浏览器直接渲染出来,可以指定容器的列个数,列间距,列中间边框,列宽度来实现

#container {

-webkit-column-count: 5;

/*-webkit-column-gap: 10px;

-webkit-column-rule: 5px solid #333;

-webkit-column-width: 210px;*/

-moz-column-count: 5;

/*-moz-column-gap: 20px;

-moz-column-rule: 5px solid #333;

-moz-column-width: 210px;*/

column-count: 5;

/*column-gap: 10px;

column-rule: 5px solid #333;

column-width: 210px;*/

}

column-count 为列数column-gap 为每列间隔距离column-rule 为间隔边线大小column-width 为每列宽度当只设置 column-width 时,浏览器窗口小于一列宽度时,列中内容自动隐藏当只设置 column-count 时,平均计算每列宽度,列内内容超出则隐藏都设了 column-count 和column-width,浏览器会根据 count 计算宽度和 width 比较,取大的那个值作为每列宽度,然后当窗口缩小时,width 的值为每列最小宽度。

3.绝对定位

可谓是最优的一种方案,方便添加数据内容,窗口变化,列数/数据块都会自动调整。