深入学习js瀑布流布局


Posted in Javascript onOctober 14, 2016

本文实例为大家分享了js瀑布流布局学习资料,供大家参考,具体内容如下

特点:等宽不等高。
实现方式:Javascript/Jquery/CSS3多栏布局。
样例网站:花瓣网-->分类

一、JS实现瀑布流

index.html:页面结构    

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>瀑布流布局</title>
  <link rel="stylesheet" href="styles/layout.css">
</head>
<body>
  <div id="main">
    <div class="box"><div class="pic"><img src="../waterFall/pic/0.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/1.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/2.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/3.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/4.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/5.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/6.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/7.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/8.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/9.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/10.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/11.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/12.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/13.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/14.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/15.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/16.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/17.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/18.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/19.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/20.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/21.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/22.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/23.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/24.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/25.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/26.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/27.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/28.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/29.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/30.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/31.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/32.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/33.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/34.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/35.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/36.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/37.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/38.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/39.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/40.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/41.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/42.jpg" alt=""></div></div>
    <div class="box"><div class="pic"><img src="../waterFall/pic/43.jpg" alt=""></div></div>
  </div>
  <script src="scripts/waterfall.js"></script>
</body>
</html>

layout.css:页面元素样式

*{
  pdding:0;
  margin:0;
}
div#main{
  position: relative;
}
div.box{
  padding:15px 0 0 15px;
  float: left;
}
div.pic{
  padding:10px;
  border:1px solid #ccc;
  border-radius:5px;
  box-shadow: 0 0 5px #ccc;
}
.pic img{
  height:auto;
  width:165px;
}

waterfall.js

window.onload=function(){
  waterFall('main','box');
  //模拟后台相应数据json
  var dataInt={
    "data":
    [
     {"src":"0.jpg"},
     {"src":"1.jpg"},
     {"src":"2.jpg"},
     {"src":"3.jpg"},
     {"src":"4.jpg"},
     {"src":"5.jpg"},
     {"src":"6.jpg"}
    ]
  }
  window.onscroll=function(){
    if(checkScrollSlide){
      //将数据块渲染到当前页面的尾部
     var oParent=document.getElementById("main");
     for(var i=0;i<dataInt.data.length;i++){
       var oBox=document.createElement("div");
       oBox.className="box";
       oParent.appendChild(oBox);
       var oPic=document.createElement("div");
       oPic.className="pic";
       oBox.appendChild(oPic);
       var img=document.createElement("img");
       img.setAttribute("src",dataInt.data[i]);
       img.src="pic/"+dataInt.data[i].src;
       oPic.appendChild(img);
     }
     dataInt=null;//清空数据块,防止无限加载
     waterFall('main','box');//对页面新元素进行布局渲染
    }
  }
}
function waterFall(parent,box){
  //将main下的class为box的所有元素取出来
  var oParent=document.getElementById(parent);
  var oBoxs=getByClass(oParent,box);
  console.log(oBoxs.length);
  //计算整个页面显示的列数(页面宽/box宽)
  var oBoxW=oBoxs[0].offsetWidth;
  // console.log(oBoxW);
  var cols=Math.floor(document.documentElement.clientWidth/oBoxW);
  // console.log(cols);
  //设置main的宽
  oParent.style.cssText="width:"+oBoxW*cols+"px;margin:0 auto;"
  var hArr=[];//存放每列高度的数组
  for(var i=0;i<oBoxs.length;i++){
    if(i<cols){
      hArr.push(oBoxs[i].offsetHeight);
    }else{
      var minH=Math.min.apply(null,hArr);//获取当前数组最小高度值
      // console.log(minH);
      var index=getMinhIndex(hArr,minH);//获取数组最小高度的索引
      //console.log(index);
      oBoxs[i].style.position="absolute";//将之后的图片依次绝对定位
      oBoxs[i].style.top=minH+"px";
      oBoxs[i].style.left=index*oBoxW+"px";//计算新图片所在的位置并赋值
      hArr[index]+=oBoxs[i].offsetHeight;//变化数组列的高度值,因为加上了一张图片
    }
    //console.log(hArr);
  }

}
//根据class获取元素
function getByClass(parent,clsName){
  var boxArr=new Array(),//用来存储获取到的所有class为box的元素
    oElements=parent.getElementsByTagName("*");
    for(var i=0;i<oElements.length;i++){
      if(oElements[i].className==clsName){
        boxArr.push(oElements[i]);
      }
    }
  return boxArr;
}
function getMinhIndex(arr,val){
  for(var i=0;i<arr.length;i++){
    if(arr[i]==val){
      return i;
    }
  }

}
//检测是否具备滚动条加载数据块条件
function checkScrollSlide(){
  var oParent=document.getElementById("main");
  var oBoxs=getByClass(oParent,"box");
  var lastBoxH=oBoxs[oBoxs.length-1].offsetTop+Math.floor(oBoxs[oBoxs.length-1].offsetHeight/2);
  var scrollTop=document.body.scrollTop||document.documentElement.scrollTop;//混杂模式和标准模式下的scrollTop获取
  //console.log(scrollTop);
  var height=document.body.clientHeight||document.documentElement.clientHeight;//混杂模式和标准模式下的浏览器窗口高度获取
  return (lastBoxH<scrollTop+height)?true:false;//检测最后一个box高度是否小于滚动高度+窗口高度,返回布尔值

}

 二、JQuery      

$( window ).on( "load", function(){
  waterfall('main','pin');
  var dataInt={'data':[{'src':'1.jpg'},{'src':'2.jpg'},{'src':'3.jpg'},{'src':'4.jpg'}]};
  window.onscroll=function(){
    if(checkscrollside()){
      $.each( dataInt.data, function( index, value ){
        var $oPin = $('<div>').addClass('pin').appendTo( $( "#main" ) );
        var $oBox = $('<div>').addClass('box').appendTo( $oPin );
        $('<img>').attr('src','./images/' + $( value).attr( 'src') ).appendTo($oBox);
      });
      waterfall();
    };
  }
});

/*
  parend 父级id
  pin 元素id
*/
function waterfall(parent,pin){
  var $aPin = $( "#main>div" );
  var iPinW = $aPin.eq( 0 ).width();// 一个块框pin的宽
  var num = Math.floor( $( window ).width() / iPinW );//每行中能容纳的pin个数【窗口宽度除以一个块框宽度】
  //oParent.style.cssText='width:'+iPinW*num+'px;ma rgin:0 auto;';//设置父级居中样式:定宽+自动水平外边距
  $( "#main" ).css({
    'width:' : iPinW * num,
    'margin': '0 auto'
  });

  var pinHArr=[];//用于存储 每列中的所有块框相加的高度。

  $aPin.each( function( index, value ){
    var pinH = $aPin.eq( index ).height();
    if( index < num ){
      pinHArr[ index ] = pinH; //第一行中的num个块框pin 先添加进数组pinHArr
    }else{
      var minH = Math.min.apply( null, pinHArr );//数组pinHArr中的最小值minH
      var minHIndex = $.inArray( minH, pinHArr );
      $( value ).css({
        'position': 'absolute',
        'top': minH + 15,
        'left': $aPin.eq( minHIndex ).position().left
      });
      //数组 最小高元素的高 + 添加上的aPin[i]块框高
      pinHArr[ minHIndex ] += $aPin.eq( index ).height() + 15;//更新添加了块框后的列高
    }
  });
}

function checkscrollside(){
  var $aPin = $( "#main>div" );
  var lastPinH = $aPin.last().get(0).offsetTop + Math.floor($aPin.last().height()/2);//创建【触发添加块框函数waterfall()】的高度:最后一个块框的距离网页顶部+自身高的一半(实现未滚到底就开始加载)
  var scrollTop = $( window ).scrollTop()//注意解决兼容性
  var documentH = $( document ).height();//页面高度
  return (lastPinH < scrollTop + documentH ) ? true : false;//到达指定高度后 返回true,触发waterfall()函数
}

三、CSS多栏布局    

.container{
  -webkit-column-width:160px;
  -moz-column-width:160px; 
   -webkit-column-gap:5px;
   -moz-column-gap:5px;
}


/*数据块 砖块*/

.container div{width:160px;
        margin:4px 0;}

【css3和js实现方法比较】
--css3方式--
1:不需要计算,浏览器自动计算,只需设置1列宽,性能高
2:列宽随着浏览器宽口大小进行改变,用户体验不好;
3:图片排序按照垂直顺序排列,打乱图片显示顺序
4.图片加载还是需要js
--js方式--
js实现的瀑布流不会有上面的缺点,但是性能相对要差!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用Javascript读取中文COOKIE的解决办法
Feb 15 Javascript
JQuery 实现的页面滚动时浮动窗口控件
Jul 10 Javascript
JS清除IE浏览器缓存的方法
Jul 26 Javascript
jQuery中add()方法用法实例
Jan 08 Javascript
jQuery使用post方法提交数据实例
Mar 25 Javascript
javascript如何实现暂停功能
Nov 06 Javascript
JavaScript中利用构造器函数模拟类的方法
Feb 16 Javascript
实战node静态文件服务器的示例代码
Mar 08 Javascript
使用layer弹窗和layui表单实现新增功能
Aug 09 Javascript
vue轻量级框架无法获取到vue对象解决方法
May 12 Javascript
js实现掷骰子小游戏
Oct 24 Javascript
如何利用JavaScript实现二叉搜索树
Apr 02 Javascript
微信小程序 地图定位简单实例
Oct 14 #Javascript
Bootstrap作品展示站点实战项目2
Oct 14 #Javascript
JS控制页面跳转时未请求要跳转的地址怎么回事
Oct 14 #Javascript
js中json处理总结之JSON.parse
Oct 14 #Javascript
Bootstrap优化站点资源、响应式图片、传送带使用详解3
Oct 14 #Javascript
D3.js封装文本实现自动换行和旋转平移等功能
Oct 14 #Javascript
D3.js实现文本的换行详解
Oct 14 #Javascript
You might like
使用php判断浏览器的类型和语言的函数代码
2013/02/28 PHP
PHP错误Warning:mysql_query()解决方法
2015/10/24 PHP
php关闭warning问题的解决方法
2016/05/17 PHP
PHP 7.4中使用预加载的方法详解
2019/07/08 PHP
CL vs ForZe BO5 第三场 2.13
2021/03/10 DOTA
常用参考资料(手册)下载或者链接
2006/07/22 Javascript
Jquery幻灯片特效代码分享--打开页面随机选择切换方式(3)
2015/08/15 Javascript
jQuery EasyUi 验证功能实例解析
2017/01/06 Javascript
js date 格式化
2017/02/15 Javascript
jQuery中的on与bind绑定事件区别实例详解
2017/02/28 Javascript
jQuery EasyUI ProgressBar进度条组件
2017/02/28 Javascript
原生JS获取元素的位置与尺寸实现方法
2017/10/18 Javascript
详解vue数组遍历方法forEach和map的原理解析和实际应用
2018/11/15 Javascript
Vue.js计算机属性computed和methods方法详解
2019/10/12 Javascript
JS实现页面鼠标点击出现图片特效
2020/08/19 Javascript
javascript使用canvas实现饼状图效果
2020/09/08 Javascript
python中List的sort方法指南
2014/09/01 Python
用Python的Django框架编写从Google Adsense中获得报表的应用
2015/04/17 Python
django之常用命令详解
2016/06/30 Python
python3 cvs将数据读取为字典的方法
2018/12/22 Python
很酷的python表白工具 你喜欢我吗
2019/04/11 Python
Python3实现配置文件差异对比脚本
2019/11/18 Python
解决pycharm debug时界面下方不出现step等按钮及变量值的问题
2020/06/09 Python
python3:excel操作之读取数据并返回字典 + 写入的案例
2020/09/01 Python
应付会计岗位职责
2013/12/12 职场文书
生日邀请函范文
2014/01/13 职场文书
有多年工作经验的自我评价
2014/03/02 职场文书
市场营销调查计划书
2014/05/02 职场文书
华清池导游词
2015/02/02 职场文书
公司宣传语大全
2015/07/13 职场文书
岗位聘任协议书
2015/09/21 职场文书
2016年春节问候语
2015/11/11 职场文书
改进工作作风心得体会
2016/01/23 职场文书
签证扫盲贴,41个常见签证知识,需要的拿走
2019/08/09 职场文书
SpringBoot整合阿里云视频点播的过程详解
2021/12/06 Java/Android
JS开发前端团队展示控制器来为成员引流
2022/08/14 Javascript