web前端进修笔记-瀑布流的算法解析与代码实现

    添加时间:2013-8-8 点击量:

    瀑布流结果今朝应用很广泛,像,新浪轻博,蘑菇街,秀丽说等很多多少网站都有.也有很多多少支撑该结果的前段框架,今天进修了一下这种结果的实现,不依附插件,本身下手解析实现过程,为了便于论述清楚,解析中的一些名词为本身制定,不当之处还瞥见谅.


     


    思路解析


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


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


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


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


     


    步调二:反复步调一,依附成行元素追加新元素


    步调一中我们已经实现了一次成行元素追加一个新的元素,如许新元素增长之后我们就构建了新的成行元素,之后的操纵就是在新的成行元素中追加新元素,道理同步调一.


    步调三:实现迁移转变地位,到底部时加载数据


    代码实现


     


    实现步调一描述结果:




    实现代码



    <!doctype html>
    
    <html>
    <head>
    <meta charset=UTF-8>
    <title>瀑布流结果实现</title>
    <script type=text/javascript src=scripts/jquery-1.8.2.min.js></script>
    <script type=text/javascript src=scripts/jquery.easydrag.handler.beta2.js></script>
    <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: + numiPinW + px;margin:0 auto;;

    var compareArray = [];
    //将一整行的瀑布流块的高度压入一个数组
    forvar i = 0; i<num; i++) {
    compareArray[i]
    = aPin[i].offsetHeight;
    }

    //获取该行瀑布流高度最低的值
    var minHeight = Math.min.apply(,compareArray);
    //alert(compareArray + ,min= + minHeight);
    //获取改行高度值小瀑布流块的索引
    var minHkey = getMinHeightKey(compareArray,minHeight);

    //为新增的瀑布流块增长样式
    aPin[num].style.position = absolute;
    aPin[num].style.top
    = minHeight + px;
    //设定新增长的瀑布流块的top和left
    aPin[num].style.left =aPin[minHkey].offsetLeft + px;

    //将该索引地位的高度改变为新增后的高度[本来瀑布流块的高度+新增的瀑布流块的高度]
    compareArray[minHkey] += aPin[num].offsetHeight;

    }
    /
    获取parent下所有样式名为className的对象凑集
    /
    function getClassObject(parent,className){
    var obj = parent.getElementsByTagName();
    var result = [];
    forvar i=0; i<obj.length;i++){
    //变量若是匹配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;
    }
    }
    }
    </script>
    <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;

    }
    </style>
    </head>
    <body>
    <div id=main>
    <!--每一个小块-->
    <div class=pin>
    <div class=box>
    <img src=images/2012110120000859759.jpg>
    </div>
    </div>

    <!--每一个小块-->
    <div class=pin>
    <div class=box>
    <img src=images/2012072300483800466.jpg>
    </div>
    </div>

    <!--每一个小块-->
    <div class=pin>
    <div class=box>
    <img src=images/2012101912011350194.jpg>
    </div>
    </div>

    <!--每一个小块-->
    <div class=pin>
    <div class=box>
    <img src=images/2012102421195356552.jpg>
    </div>
    </div>

    <!--每一个小块-->
    <div class=pin>
    <div class=box>
    <img src=images/2012072312335411883.jpg>
    </div>
    </div>


    <!--每一个小块-->
    <div class=pin>
    <div class=box>
    <img src=images/2012082910221472225.jpg>
    </div>
    </div>


    </div>
    </body>
    </html>


    实现步调二描述结果

    实现代码



    <!doctype html>
    
    <html>
    <head>
    <meta charset=UTF-8>
    <title>瀑布流结果实现</title>
    <script type=text/javascript src=scripts/jquery-1.8.2.min.js></script>
    <script type=text/javascript src=scripts/jquery.easydrag.handler.beta2.js></script>
    <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: + numiPinW + px;margin:0 auto;;

    var compareArray = [];
    //遍历获取到的所有瀑布流块
    forvar i = 0; i<aPin.length; i++) {
    if(i<num){
    //成行元素
    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 = [];
    forvar i=0; i<obj.length;i++){
    //变量若是匹配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;
    }
    }
    }
    </script>
    <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;

    }
    </style>
    </head>
    <body>
    <div id=main>
    <!--每一个小块-->
    <div class=pin>
    <div class=box>
    <img src=images/2012110120000859759.jpg>
    </div>
    </div>

    <!--每一个小块-->
    <div class=pin>
    <div class=box>
    <img src=images/2012072300483800466.jpg>
    </div>
    </div>

    <!--每一个小块-->
    <div class=pin>
    <div class=box>
    <img src=images/2012101912011350194.jpg>
    </div>
    </div>

    <!--每一个小块-->
    <div class=pin>
    <div class=box>
    <img src=images/2012102421195356552.jpg>
    </div>
    </div>

    <!--每一个小块-->
    <div class=pin>
    <div class=box>
    <img src=images/2012072312335411883.jpg>
    </div>
    </div>

    <!--每一个小块-->
    <div class=pin>
    <div class=box>
    <img src=images/2012082910221472225.jpg>
    </div>
    </div>

    <!--每一个小块-->
    <div class=pin>
    <div class=box>
    <img src=images/2012082910024626515.jpg>
    </div>
    </div>

    </div>
    </body>
    </html>


    会看到新增的瀑布流块在新的成行元素中主动寻找高度最低的那个元素块的相对地位进行追加.添加更多元素查看结果


    步调三:实现迁移转变到底部时加载数据
    该项目组没有什么功能,只是检测迁移转变条的地位间隔浏览器底部的相对间隔进行数据加载,加载数据时创建对应的瀑布流块.断定相对间隔的实现逻辑如下



            function checkScrollSite(){
    
    var oParent = document.getElementById(main);

    var aPin = getClassObject(oParent,pin);
    //加载数据依附最后一个瀑布流块变更
    var lastPinHeight = aPin[aPin.length-1].offsetTop + Math.floor(aPin[aPin.length-1].offsetHeight/2) ;
    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    //浏览器高度
    var documentH = document.documentElement.clientHeight;

    if(lastPinHeight
    <documentH + scrollTop){
    //恳求数据
    return true;
    }
    return false;
    }


    在此感激,郑印在进修上赐与的领导.

    转载请注明出处:[http://www.cnblogs.com/dennisit/p/3244987.html]


     

    彼此相爱,却不要让爱成了束缚:不如让它成为涌动的大海,两岸乃是你们的灵魂。互斟满杯,却不要同饮一杯。相赠面包,却不要共食一个。一起歌舞欢喜,却依然各自独立,相互交心,却不是让对方收藏。因为唯有生命之手,方能收容你们的心。站在一起却不要过于靠近。—— 纪伯伦《先知》
    分享到: