解析瀑布流布局: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 相关文章推荐
同一页面多个商品倒计时JS 基于面向对象的javascript
Feb 16 Javascript
js切换div css注意的细节
Dec 10 Javascript
javascript窗口宽高,鼠标位置,滚动高度(详细解析)
Nov 18 Javascript
JS获取当前网页大小以及屏幕分辨率等
Sep 05 Javascript
莱鸟介绍window.print()方法
Jan 06 Javascript
10个JavaScript中易犯小错误
Feb 14 Javascript
Jquery修改image的src属性,图片不加载问题的解决方法
May 17 Javascript
Bootstrap实现各种进度条样式详解
Apr 13 Javascript
QRCode.js:基于JQuery的生成二维码JS库的使用
Jun 23 jQuery
JavaScript反射与依赖注入实例详解
May 29 Javascript
vue的列表交错过渡实现代码示例
May 05 Javascript
我要点爆”微信小程序云开发之项目建立与我的页面功能实现
May 26 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
Linux环境下搭建php开发环境的操作步骤
2013/06/17 PHP
php中http与https跨域共享session的解决方法
2014/12/20 PHP
如何使用PHP Embed SAPI实现Opcodes查看器
2015/11/10 PHP
JavaScript 克隆数组最简单的方法
2009/02/12 Javascript
ASP中进行HTML数据及JS数据编码函数
2009/11/11 Javascript
javascipt基础内容--需要注意的细节
2013/04/10 Javascript
window.onload追加函数使用示例
2014/03/03 Javascript
js判断鼠标左、中、右键哪个被点击的方法
2015/01/27 Javascript
Javascript 动态改变imput type属性
2016/11/01 Javascript
Angular的模块化(代码分享)
2016/12/26 Javascript
JavaScript &amp; jQuery完美判断图片是否加载完毕
2017/01/08 Javascript
vue2的todolist入门小项目的详细解析
2017/05/11 Javascript
微信小程序 如何引入外部字体库iconfont的图标
2018/01/31 Javascript
基于express中路由规则及获取请求参数的方法
2018/03/12 Javascript
使用json-server简单完成CRUD模拟后台数据的方法
2018/07/12 Javascript
使用 Vue-TCB 快速在 Vue 应用中接入云开发的方法
2020/02/10 Javascript
js实现鼠标滑动到某个div禁止滚动
2020/09/17 Javascript
[01:55]2014DOTA2国际邀请赛快报:国土生病 紧急去医院治疗
2014/07/10 DOTA
Python入门之三角函数全解【收藏】
2017/11/08 Python
Python3之文件读写操作的实例讲解
2018/01/23 Python
利用pyecharts读取csv并进行数据统计可视化的实现
2020/04/17 Python
Python列表去重复项的N种方法(实例代码)
2020/05/12 Python
python音频处理的示例详解
2020/12/23 Python
K近邻法(KNN)相关知识总结以及如何用python实现
2021/01/28 Python
html5启动原生APP总结
2020/07/03 HTML / CSS
台湾饭店和机票预订网站:Expedia台湾
2016/08/05 全球购物
英国男士时尚购物网站:Stuarts London
2017/10/22 全球购物
UNIX文件系统常用命令
2012/05/25 面试题
护理学毕业生求职信
2013/11/14 职场文书
适用于所有创业者的创业计划书
2014/02/05 职场文书
创新比赛获奖感言
2014/02/13 职场文书
北京故宫导游词
2015/01/31 职场文书
2015年学雷锋活动总结
2015/02/06 职场文书
预备党员半年考察意见
2015/06/01 职场文书
html5+实现plus.io进行拍照和图片等获取
2022/06/01 HTML / CSS
使用 DataAnt 监控 Apache APISIX的原理解析
2022/07/07 Servers