• 瀑布流布局——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

    复制代码
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     <html xmlns="http://www.w3.org/1999/xhtml">
     <head>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
     <meta name="anchor" content="who care?" />
     <script type="text/javascript" src="waterfall.js"/></script>
     
     <title></title>
     <style type="text/css">
         *{padding: 0;margin:0;}
         #main{
             position: relative;
         }
         .pin{
             padding: 15px 0 0 15px;
             float:left;
         }
         .box{
             padding: 10px;
             border:1px solid #ccc;
             box-shadow: 0 0 6px #ccc;
             border-radius: 5px;
         }
         .box img{
             width:162px;
             height:auto;
         }
     </style>
     </head>
     <body>
     <div id="main">
         <div class="pin">
             <div class="box">
                 <img src="./images/g (1).jpg"/>
             </div>
         </div>
         <div class="pin">
             <div class="box">
                 <img src="./images/g (2).jpg"/>
             </div>
         </div>
         <div class="pin">
             <div class="box">
                 <img src="./images/g (3).jpg"/>
             </div>
         </div>
         <div class="pin">
             <div class="box">
                 <img src="./images/g (4).jpg"/>
             </div>
         </div>
         <div class="pin">
             <div class="box">
                 <img src="./images/g (5).jpg"/>
             </div>
         </div>
     </div>
     </body>
     </html>
    复制代码

    js:waterfall.js

    复制代码
    window.onload=function(){
    waterfall('main','pin');
         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'); //添加 元素节点
                 oPin.className='pin';                   //添加 类名 name属性
                 oParent.appendChild(oPin);              //添加 子节点
                 var oBox=document.createElement('div');
                 oBox.className='box';
                 oPin.appendChild(oBox);
                 var oImg=document.createElement('img');
                 oImg.src='./images/'+dataInt.data[i].src;
                 oBox.appendChild(oImg);
             }
             waterfall('main','pin');
             };
         }
         
     }
     /*
             parend 父级id
             pin 元素id
     */
     function waterfall(parent,pin){
         var oParent=document.getElementById(parent);// 父级对象
         var aPin=getClassObj(oParent,pin);// 获取存储块框pin的数组aPin
         var iPinW=aPin[0].offsetWidth;// 一个块框pin的宽
         var num=Math.floor(document.documentElement.clientWidth/iPinW);//每行中能容纳的pin个数【窗口宽度除以一个块框宽度】
         oParent.style.cssText=''+iPinW*num+'px;ma rgin:0 auto;';//设置父级居中样式:定宽+自动水平外边距
     
         var pinHArr=[];//用于存储 每列中的所有块框相加的高度。
         for(var i=0;i<aPin.length;i++){//遍历数组aPin的每个块框元素
             var pinH=aPin[i].offsetHeight;
             if(i<num){
                 pinHArr[i]=pinH; //第一行中的num个块框pin 先添加进数组pinHArr
             }else{
                 var minH=Math.min.apply(null,pinHArr);//数组pinHArr中的最小值minH
                 var minHIndex=getminHIndex(pinHArr,minH);
                 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;//更新添加了块框后的列高
             }
         }
     }
         /****
             *通过父级和子元素的class类 获取该同类子元素的数组
             */
         function getClassObj(parent,className){
             var obj=parent.getElementsByTagName('*');//获取 父级的所有子集
             var pinS=[];//创建一个数组 用于收集子元素
             for (var i=0;i<obj.length;i++) {//遍历子元素、判断类别、压入数组
                 if (obj[i].className==className){
                     pinS.push(obj[i]);
                 }
             };
             return pinS;
         }
         /****
             *获取 pin高度 最小值的索引index
             */
         function getminHIndex(arr,minH){
             for(var i in arr){
                 if(arr[i]==minH){
                     return i;
                 }
             }
         }
     
     
         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()函数
         }
    复制代码
  • 相关阅读:
    null和undefined的区别
    【面试】前端面试题总结一(css)
    【js基础类】火狐的滚动事件
    【Vue】provide和inject
    React学习:react-router-dom-主要组件
    React学习:组合VS继承
    React学习:状态提升
    React学习:form表单
    unity+ARKit 捕捉表情录制动画 表情动画与人形骨骼动画融合
    Unity导入模型材质球无法编辑属性解决方法
  • 原文地址:https://www.cnblogs.com/lglijing/p/3337317.html
Copyright © 2020-2023  润新知