解析瀑布流布局:JS+绝对定位的实现


Posted in Javascript onMay 08, 2013

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

一、布局

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;}

效果:

解析瀑布流布局:JS+绝对定位的实现

二、思路:

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='width:'+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()函数
    }

三、最终效果:解析瀑布流布局:JS+绝对定位的实现

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

五、完成后的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 1 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='width:'+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()函数
     }
Javascript 相关文章推荐
List Installed Hot Fixes
Jun 12 Javascript
DIV外区域Click后关闭DIV的实现代码
Dec 21 Javascript
基于jQuery实现模拟页面加载进度条
Apr 01 Javascript
获得Javascript对象属性个数的示例代码
Nov 21 Javascript
jQuery下拉友情链接美化效果代码分享
Aug 26 Javascript
微信小程序 页面传参实例详解
Nov 16 Javascript
js实现移动端轮播图效果
Dec 09 Javascript
详解angular如何调用HTML字符串的方法
Jun 30 Javascript
详解Koa中更方便简单发送响应的方式
Jul 20 Javascript
vue-cli项目使用mock数据的方法(借助express)
Apr 15 Javascript
JavaScript链式调用原理与实现方法详解
May 16 Javascript
JavaScript 如何计算文本的行数的实现
Sep 14 Javascript
JavaScript 对任意元素,自定义右键菜单的实现方法
May 08 #Javascript
深入document.write()与HTML4.01的非成对标签的详解
May 08 #Javascript
使用JavaScript 实现各种跨域的方法
May 08 #Javascript
jQuery根据纬度经度查看地图处理程序
May 08 #Javascript
使用JavaScript 实现对象 匀速/变速运动的方法
May 08 #Javascript
JavaScript 创建运动框架的实现代码
May 08 #Javascript
jQuery输入城市查看地图使用介绍
May 08 #Javascript
You might like
PHP,ASP.JAVA,JAVA代码格式化工具整理
2010/06/15 PHP
《PHP编程最快明白》第五讲:php目录、文件操作
2010/11/01 PHP
解析PHP生成静态html文件的三种方法
2013/06/18 PHP
codeigniter自带数据库类使用方法说明
2014/03/25 PHP
ThinkPHP实现将SESSION存入MYSQL的方法
2014/07/22 PHP
PHP自定session保存路径及删除、注销与写入的方法
2014/11/18 PHP
Centos下升级php5.2到php5.4全记录(编译安装)
2015/04/03 PHP
UTF-8正则表达式如何匹配汉字
2015/08/03 PHP
Zend Framework教程之模型Model基本规则和使用方法
2016/03/04 PHP
利用Laravel生成Gravatar头像地址的优雅方法
2017/12/30 PHP
php 函数中静态变量使用的问题实例分析
2020/03/05 PHP
从sohu弄下来的flash中展示图片的代码
2007/04/27 Javascript
Prototype Array对象 学习
2009/07/19 Javascript
JQuery 拾色器插件发布-jquery.icolor.js
2010/10/20 Javascript
jQuery在vs2008及js文件中的无智能提示的解决方法
2010/12/30 Javascript
js复制网页内容并兼容各主流浏览器的代码
2013/12/17 Javascript
jQuery源码解读之hasClass()方法分析
2015/02/20 Javascript
图片旋转、鼠标滚轮缩放、镜像、切换图片js代码
2020/12/13 Javascript
javascript表单处理具体实现代码(表单、链接、按钮)
2016/05/07 Javascript
微信小程序 网络API Websocket详解
2016/11/09 Javascript
JS实现获取来自百度,Google,soso,sogou关键词的方法
2016/12/21 Javascript
深入理解Webpack 中路径的配置
2017/06/17 Javascript
通过Python爬虫代理IP快速增加博客阅读量
2016/12/14 Python
Python获取指定文件夹下的文件名的方法
2018/02/06 Python
Python切片索引用法示例
2018/05/15 Python
python将.ppm格式图片转换成.jpg格式文件的方法
2018/10/27 Python
Python3.7 新特性之dataclass装饰器
2019/05/27 Python
python对验证码降噪的实现示例代码
2019/11/12 Python
Prototype中如何为一个元素添加一个方法
2014/12/08 面试题
行政专员岗位职责
2014/01/02 职场文书
车间安全生产标语
2014/06/06 职场文书
月度优秀员工获奖感言
2014/08/16 职场文书
开展党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
群众对十八届四中全会的期盼
2014/10/17 职场文书
岗位聘任报告
2015/03/02 职场文书
红楼梦读书笔记
2015/06/25 职场文书