zoukankan      html  css  js  c++  java
  • 瀑布流布局——JS+绝对定位

    绝对定位方式的瀑布流布局:

    一、布局

    1、包围块框的容器:

    <div id="main">
        ... ...
    <div>

    2、一个块框:

    <div class="pin">
        <div class="box">
            <img src="./images/g (1).jpg"/>
        </div>
    </div>

    3、初始化第一行/5个块框:

        .pin{
            padding: 15px 0 0 15px;
            float: left;}
        .box{
            padding: 10px;
            border:1px solid #ccc;}
        .box img{
            width:192px;
            height:auto;}

     

     效果:

     二、思路:

    1、设置父级main的样式:水平居中。
    2、设置每个块框pin的样式:绝对定位。
    3、设置窗口滚动事件的监听函数:读取数据添加块框。

    JS实现:

      1-①:获取父级oParent:
      1-②:创建函数getClassObj()-通过父级id和块框类名-获取包含块框的数组。

        var oParent=document.getElementById('main');// 父级对象
        var aPin=getClassObj(oParent,pin);// 获取存储块框pin的数组aPin
        var num=Math.floor(document.documentElement.clientWidth/aPin[0].offsetWidth);//获取-每行中能容纳的块框个数-num【窗口宽度除以一个块框宽度】
      oParent.style.cssText=''+iPinW*num+'px;margin:0 auto;';//用cssText属性为父级main添加居中样式:定宽+自动水平外边距
        function getClassObj(parent,className){
            var obj=parent.getElementsByTagName('*');//获取 父级的所有子集
            var pinS=[];//创建一个数组 用于存储类为className的元素
            for (var i=0;i<obj.length;i++) {//遍历子集、判断类名、压入数组
                if (obj[i].className==className)
                    pinS.push(obj[i]);
            };
            return pinS;}

     

      2-①:创建数组pinHArr-用于存储每一列高度;
      2-②:for语句遍历每个块框aPin[i],将前num个块框赋值给数组pinHArr,对超出一行能容纳的块框数num的块框绝对定位。
      2-③:用创建函数getminHIndex()-返回一个数组中的最小值

        var pinHArr=[];//用于存储 每列中的所有块框相加的高度【随着列数的不同此数组的length也随之改变】
        for(var i=0;i<aPin.length;i++){//遍历数组aPin的每个块框元素
            var pinH=aPin[i].offsetHeight;//获取数组aPin的第i个块框的可见宽offsetHeight
            if(i<num){//
                pinHArr[i]=pinH; //第一行中的num个块框aPin 先添加进数组pinHArr
            }else{
                var minH=Math.min.apply(null,pinHArr);//计算数组pinHArr中的最小值minH
                var minHIndex=getminHIndex(pinHArr,minH);//通过创建的getminHIndex()-获取最小值minH在数组pinHArr中的索引minHIndex
                aPin[i].style.position='absolute';//设置绝对位移
                aPin[i].style.top=minH+'px';
                aPin[i].style.left=aPin[minHIndex].offsetLeft+'px';//数组 最小高元素的高 + 添加上的aPin[i]块框高
                pinHArr[minHIndex]+=aPin[i].offsetHeight;//更新添加块框后的列高
            }
        }
        function getminHIndex(arr,minH){
            for(var i in arr){
                if(arr[i]==minH)return i;
            }
        }

     

       3:设置窗口滚动事件的监听函数:读取数据添加块框。

        var dataInt={'data':[{'src':'g (1).jpg'},{'src':'g (9).jpg'},{'src':'g (2).jpg'},{'src':'g (4).jpg'}]};//一个临时的数据对象
        //下面定义窗口滚动事件监听函数
        window.onscroll=function(){
            if(checkscrollside()){
            var oParent=document.getElementById('main');// 父级对象
            for(var i=0;i<dataInt.data.length;i++){
                var oPin=document.createElement('div'); //创建添加 元素节点pin
                oPin.className='pin';                   //添加 类名 name属性
                oParent.appendChild(oPin);              //创建添加 子节点box
                var oBox=document.createElement('div');
                oBox.className='box';
                oPin.appendChild(oBox);
                var oImg=document.createElement('img');//创建添加 子节点img
                oImg.src='./images/'+dataInt.data[i].src;
                oBox.appendChild(oImg);
            }
            waterfall('main','pin');//将①②封装成函数waterfall(),将添加的节点添加到添加和定位到文档中。
            };
        }

     

        function checkscrollside(){
            var oParent=document.getElementById('main');
            var aPin=getClassObj(oParent,'pin');
            var lastPinH=aPin[aPin.length-1].offsetTop+Math.floor(aPin[aPin.length-1].offsetHeight/2);//创建【触发添加块框函数waterfall()】的高度:最后一个块框的距离网页顶部+自身高的一半(实现未滚到底就开始加载)
            var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;//注意解决兼容性
            var documentH=document.documentElement.clientHeight;//窗口高度
            return (lastPinH<scrollTop+documentH)?true:false;//到达指定高度后 返回true,触发waterfall()函数
        }

     

     三、最终效果:

     

    四、总结:此为让自己梳理一下思路,表达不太仔细连贯,仅供参考。

     

     

    五、完成后的html文件和js文件:

    html:index.html

     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     2 <html xmlns="http://www.w3.org/1999/xhtml">
     3 <head>
     4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
     5 <meta name="anchor" content="who care?" />
     6 <script type="text/javascript" src="waterfall.js"/></script>
     7 
     8 <title></title>
     9 <style type="text/css">
    10     *{padding: 0;margin:0;}
    11     #main{
    12         position: relative;
    13     }
    14     .pin{
    15         padding: 15px 0 0 15px;
    16         float:left;
    17     }
    18     .box{
    19         padding: 10px;
    20         border:1px solid #ccc;
    21         box-shadow: 0 0 6px #ccc;
    22         border-radius: 5px;
    23     }
    24     .box img{
    25         width:162px;
    26         height:auto;
    27     }
    28 </style>
    32 </head>
    33 <body>
    34 <div id="main">
    35     <div class="pin">
    36         <div class="box">
    37             <img src="./images/g (1).jpg"/>
    38         </div>
    39     </div>
    40     <div class="pin">
    41         <div class="box">
    42             <img src="./images/g (2).jpg"/>
    43         </div>
    44     </div>
    45     <div class="pin">
    46         <div class="box">
    47             <img src="./images/g (3).jpg"/>
    48         </div>
    49     </div>
    50     <div class="pin">
    51         <div class="box">
    52             <img src="./images/g (4).jpg"/>
    53         </div>
    54     </div>
    55     <div class="pin">
    56         <div class="box">
    57             <img src="./images/g (5).jpg"/>
    58         </div>
    59     </div>
    60 </div>
    61 </body>
    62 </html>

    js:waterfall.js 1 window.onload=function(){

     2     waterfall('main','pin');
     3     var dataInt={'data':[{'src':'g (1).jpg'},{'src':'g (9).jpg'},{'src':'g (2).jpg'},{'src':'g (4).jpg'}]};
     4     
     5     window.onscroll=function(){
     6         if(checkscrollside()){
     7         var oParent=document.getElementById('main');// 父级对象
     8         for(var i=0;i<dataInt.data.length;i++){
     9             var oPin=document.createElement('div'); //添加 元素节点
    10             oPin.className='pin';                   //添加 类名 name属性
    11             oParent.appendChild(oPin);              //添加 子节点
    12             var oBox=document.createElement('div');
    13             oBox.className='box';
    14             oPin.appendChild(oBox);
    15             var oImg=document.createElement('img');
    16             oImg.src='./images/'+dataInt.data[i].src;
    17             oBox.appendChild(oImg);
    18         }
    19         waterfall('main','pin');
    20         };
    21     }
    22     
    23 }
    24 /*
    25         parend 父级id
    26         pin 元素id
    27 */
    28 function waterfall(parent,pin){
    29     var oParent=document.getElementById(parent);// 父级对象
    30     var aPin=getClassObj(oParent,pin);// 获取存储块框pin的数组aPin
    31     var iPinW=aPin[0].offsetWidth;// 一个块框pin的宽
    32     var num=Math.floor(document.documentElement.clientWidth/iPinW);//每行中能容纳的pin个数【窗口宽度除以一个块框宽度】
    33     oParent.style.cssText=''+iPinW*num+'px;ma rgin:0 auto;';//设置父级居中样式:定宽+自动水平外边距
    34 
    35     var pinHArr=[];//用于存储 每列中的所有块框相加的高度。
    36     for(var i=0;i<aPin.length;i++){//遍历数组aPin的每个块框元素
    37         var pinH=aPin[i].offsetHeight;
    38         if(i<num){
    39             pinHArr[i]=pinH; //第一行中的num个块框pin 先添加进数组pinHArr
    40         }else{
    41             var minH=Math.min.apply(null,pinHArr);//数组pinHArr中的最小值minH
    42             var minHIndex=getminHIndex(pinHArr,minH);
    43             aPin[i].style.position='absolute';//设置绝对位移
    44             aPin[i].style.top=minH+'px';
    45             aPin[i].style.left=aPin[minHIndex].offsetLeft+'px';
    46             //数组 最小高元素的高 + 添加上的aPin[i]块框高
    47             pinHArr[minHIndex]+=aPin[i].offsetHeight;//更新添加了块框后的列高
    48         }
    49     }
    50 }
    51     /****
    52         *通过父级和子元素的class类 获取该同类子元素的数组
    53         */
    54     function getClassObj(parent,className){
    55         var obj=parent.getElementsByTagName('*');//获取 父级的所有子集
    56         var pinS=[];//创建一个数组 用于收集子元素
    57         for (var i=0;i<obj.length;i++) {//遍历子元素、判断类别、压入数组
    58             if (obj[i].className==className){
    59                 pinS.push(obj[i]);
    60             }
    61         };
    62         return pinS;
    63     }
    64     /****
    65         *获取 pin高度 最小值的索引index
    66         */
    67     function getminHIndex(arr,minH){
    68         for(var i in arr){
    69             if(arr[i]==minH){
    70                 return i;
    71             }
    72         }
    73     }
    74 
    75 
    76     function checkscrollside(){
    77         var oParent=document.getElementById('main');
    78         var aPin=getClassObj(oParent,'pin');
    79         var lastPinH=aPin[aPin.length-1].offsetTop+Math.floor(aPin[aPin.length-1].offsetHeight/2);//创建【触发添加块框函数waterfall()】的高度:最后一个块框的距离网页顶部+自身高的一半(实现未滚到底就开始加载)
    80         var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;//注意解决兼容性
    81         var documentH=document.documentElement.clientHeight;//页面高度
    82         return (lastPinH<scrollTop+documentH)?true:false;//到达指定高度后 返回true,触发waterfall()函数
    83     }
    
    
    
    
    
    
  • 相关阅读:
    telnet命令找不到问题
    hive向表中执行insert语句报错问题
    SharePoint 2010 日期控件(DateTimeControl)的用法
    SharePoint 2010 启用InfoPath支持
    Sharepoint 2010 根据用户权限隐藏Ribbon菜单
    Sharepoint 2010 使用feature部署文件
    SharePoint 2010 查询不以某个字符开头的数据[How to Create a SharePoint “Does Not Begin With” Filtered List View]计算栏的妙用
    SharePoint 2010 栏计算经验收集
    SharePoint 2010 更加列表栏的值显示不同的背景颜色
    SharePoint 2010 使用SP.UI.ModalDialog.showModalDialog(options)对话框框架传值
  • 原文地址:https://www.cnblogs.com/slowsoul/p/2909746.html
Copyright © 2011-2022 走看看