深入学习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判断两种格式的输入日期的正确性的代码
Mar 25 Javascript
JS在textarea光标处插入文本的小例子
Mar 22 Javascript
jQuery老黄历完整实现方法
Jan 16 Javascript
详解 javascript中offsetleft属性的用法
Nov 11 Javascript
JavaScript中将数组进行合并的基本方法讲解
Mar 07 Javascript
深入理解bootstrap框架之入门准备
Oct 09 Javascript
JS调用某段SQL语句的方法
Oct 20 Javascript
jQuery插件FusionCharts实现的2D面积图效果示例【附demo源码下载】
Mar 06 Javascript
利用JavaScript在网页实现八数码启发式A*算法动画效果
Apr 16 Javascript
Webpack实战加载SVG的方法
Dec 26 Javascript
微信小程序使用template标签实现五星评分功能
Nov 03 Javascript
Vue中使用import进行路由懒加载的原理分析
Apr 01 Vue.js
微信小程序 地图定位简单实例
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和js交互一例-PHP教程,PHP应用
2007/01/03 PHP
PHP排序算法之希尔排序(Shell Sort)实例分析
2018/04/20 PHP
Yii实现微信公众号场景二维码的方法实例
2020/08/30 PHP
JavaScript 选中文字并响应获取的实现代码
2011/08/28 Javascript
一行代码告别document.getElementById
2012/06/01 Javascript
javascript学习笔记(一) 在html中使用javascript
2012/06/18 Javascript
node.js集成百度UE编辑器
2015/02/05 Javascript
js将字符串中的每一个单词的首字母变为大写其余均为小写
2017/01/05 Javascript
微信小程序Server端环境配置详解(SSL, Nginx HTTPS,TLS 1.2 升级)
2017/01/12 Javascript
正则验证小数点后面只能有两位数的方法
2017/02/28 Javascript
jQuery阻止移动端遮罩层后页面滚动
2017/03/15 Javascript
Node.js如何使用Diffie-Hellman密钥交换算法详解
2017/09/05 Javascript
JS中双击和单击事件冲突的解决方法
2018/04/09 Javascript
基于Vue的延迟加载插件vue-view-lazy
2018/05/21 Javascript
JavaScript类的继承操作实例总结
2018/12/20 Javascript
小程序云开发如何实现图片上传及发表文字
2019/05/17 Javascript
vue中监听返回键问题
2019/08/28 Javascript
[50:44]DOTA2-DPC中国联赛 正赛 SAG vs Dragon BO3 第二场 2月22日
2021/03/11 DOTA
pyqt和pyside开发图形化界面
2014/01/22 Python
python实现超市扫码仪计费
2018/05/30 Python
python3将视频流保存为本地视频文件
2018/06/20 Python
django-rest-framework解析请求参数过程详解
2019/07/18 Python
Python交互式图形编程的实现
2019/07/25 Python
Numpy将二维数组添加到空数组的实现
2019/12/05 Python
使用Python测试Ping主机IP和某端口是否开放的实例
2019/12/17 Python
Python 改变数组类型为uint8的实现
2020/04/09 Python
圣诞树世界:Christmas Tree World
2019/12/10 全球购物
新西兰最大的天然保健及护肤品网站:HealthPost(直邮中国)
2021/02/13 全球购物
沙特阿拉伯排名第一的在线时尚购物应用程序:1Zillion
2020/08/08 全球购物
XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式?
2016/01/12 面试题
车贷收入证明范本
2014/01/09 职场文书
什么样的创业计划书可行性高?
2014/02/01 职场文书
计生个人工作总结
2015/02/28 职场文书
《颐和园》教学反思
2016/02/19 职场文书
Mybatis-plus配置分页插件返回统一结果集
2022/06/21 Java/Android
MySQL事务的ACID特性以及并发问题方案
2022/07/15 MySQL