瀑布流的实现方式(原生js+jquery+css3)
来源: 阅读:1099 次 日期:2016-07-27 16:10:07
温馨提示: 小编为您整理了“瀑布流的实现方式(原生js+jquery+css3)”,方便广大网友查阅!

这篇文章主要为大家详细介绍了原生js+jquery+css3实现瀑布流的相关代码,三种实现瀑布流的方法,感兴趣的小伙伴们可以参考一下

前言

项目需求要弄个瀑布流的页面,用的是waterfall这个插件,感觉还是可以的,项目赶就没自己的动手写。最近闲来没事,就自己写个。大致思路理清楚,还是挺好实现的... 

原生javascript版 

<!DOCTYPE html>

<html lang="en">

<head>

 <meta charset="UTF-8">

 <title>瀑布流-javascript</title>

 <style>

 *{margin:0;padding:0;}

 #content{position: relative;margin:0 auto;}

 .box{padding:10px;float: left;}/*首行浮动,第二行开始绝对定位*/

 .box img{width: 180px;height:auto;display: block;}

 </style>

 <script>

 window.onload=function(){

  waterfall('content','box');

  //改变窗口大小时,重新排列

  window.onresize = function(){

  waterfall('content','box');

  }

  //如果数据不够,没出现滚动条,自动加载数据

  var time=setInterval(function(){

  if(checkscrollside()){

   addDate();//插入数据

   waterfall('content','box');//加载完数据从新排列

  }else{

   clearInterval(time);

   window.onscroll=function(){

   if(checkscrollside()){

    addDate();

    waterfall('content','box');

   };

   }

  }

  },1000) 

 } 

 // 数据插入

 function addDate(){

  var dataInt=['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg','6.jpg','7.jpg','8.jpg'];//模拟数据,也可以是对象

  var oParent = document.getElementById('content');

  for(var i=0;i<dataInt.length;i++){//循环插入数据 

  var oBox=document.createElement('div');

  oBox.className='box';

  oParent.appendChild(oBox);

  var oImg=document.createElement('img');

  oImg.src='./img/'+dataInt[i];

  oBox.appendChild(oImg);

  }

 }

 //主函数

 function waterfall(parentID,childClass){

  var oParent=document.getElementById(parentID);

  var arrBox=getClassObj(parentID,childClass);// getClassObj()获取子class的数组

  var iBoxW=arrBox[0].offsetWidth;// 获取瀑布流块的宽度

  var num=Math.floor(document.documentElement.clientWidth/iBoxW);//计算窗口能容纳几列

  oParent.style.width=iBoxW*num+'px';//设置父级宽度

  var arrBoxH=[];//数组,用于存储每列中的所有块框相加的高度

  for(var i=0;i<arrBox.length;i++){//遍历数组瀑布流 块

  var boxH=arrBox[i].offsetHeight;//获取当前块的高度

  if(i<num){

   arrBox[i].style.cssText="";//防止用户改变窗口大小,到时样式出错

   arrBoxH[i]=boxH; //第一行中的num个块box 先添加进数组arrBoxH

  }else{

   var minH=Math.min.apply(null,arrBoxH);//获取数组arrBoxH中的最小值minH

   var minHIndex=getminHIndex(arrBoxH,minH);//遍历数组获取最小值minH的索引

   arrBox[i].style.position='absolute';//设置绝对位移

   arrBox[i].style.top=minH+'px';

   arrBox[i].style.left=minHIndex*iBoxW+'px';//也可以直接获取arrBox[minHIndex].offsetLeft

   arrBoxH[minHIndex]+=arrBox[i].offsetHeight;//添加后,更新最小列高

  }

  }

 }

 //获取子class的数组

 function getClassObj(parentID,childClass){

  var oParent=document.getElementById(parentID);

  var allChildObj=oParent.getElementsByTagName('*');//获取父级下的所有子集

  var childObj=[];//创建一个数组 用于收集子元素

  for (var i=0;i<allChildObj.length;i++) {//遍历子元素、判断类别、压入数组

  if (allChildObj[i].className==childClass){

   childObj.push(allChildObj[i]);

  }

  };

  return childObj;

 }

 //获取数组最小值的索引

 function getminHIndex(arr,minH){

  for(var i in arr){

  if(arr[i]==minH){

   return i;

  }

  }

 }

 // 判断滚动条是否到底部

 function checkscrollside(){

  var arrBox=getClassObj("content",'box');

  //获取最后一个瀑布流块的高度:距离网页顶部(实现未滚到底就开始加载)

  var lastBoxH=arrBox[arrBox.length-1].offsetTop;

  var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;//获取滚动条卷走的高度

  var documentH=document.documentElement.clientHeight;//显示页面文档的高

  return (lastBoxH<scrollTop+documentH)?true:false;//到达指定高度后 返回true,触发waterfall()函数

 }

 </script>

</head>

<body>

 <div id="content">

 <div class="box"><img src="img/0.jpg" alt=""></div>

 <div class="box"><img src="img/1.jpg" alt=""></div>

 <div class="box"><img src="img/2.jpg" alt=""></div>

 <div class="box"><img src="img/3.jpg" alt=""></div>

 <div class="box"><img src="img/4.jpg" alt=""></div>

 <div class="box"><img src="img/5.jpg" alt=""></div>

 <div class="box"><img src="img/6.jpg" alt=""></div>

 <div class="box"><img src="img/7.jpg" alt=""></div>

 <div class="box"><img src="img/8.jpg" alt=""></div>

 <div class="box"><img src="img/9.jpg" alt=""></div>

 <div class="box"><img src="img/10.jpg" alt=""></div>

 </div>

</body>

</html>

jquery版本 

<!DOCTYPE html>

<html lang="en">

<head>

 <meta charset="UTF-8">

 <title>瀑布流-jquery</title>

 <style>

 *{margin:0;padding:0;}

 #content{position: relative;margin:0 auto;}

 .box{padding:10px;float: left;}

 .box img{width: 180px;height:auto;display: block;}

 </style>

 <script src="js/jquery-1.11.1.min.js"></script>

 <script>

 $(function(){

  waterfall();

  //改变窗口大小时,重新排列

  $(window).resize(function(){

  waterfall();

  })

  //如果数据不够,没出现滚动条,自动加载数据

  var time=setInterval(function(){

  if(checkscrollside()){

   addDate();//插入数据

   waterfall();//加载完数据从新排列

  }else{

   clearInterval(time);

   $(window).scroll(function(){

   if(checkscrollside()){

    addDate();

    waterfall();

   };

   })

  }

  },1000) 

 }) 

 // 数据插入

 function addDate(){

  var dataInt=['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg','6.jpg','7.jpg','8.jpg'];//模拟数据,也可以是对象

  var oParent = $('#content');

  for(var i=0;i<dataInt.length;i++){//循环插入数据

  oParent.append('<div class="box"><img src="./img/'+dataInt[i]+'" alt=""></div>'); 

  }

 }

 //主函数

 function waterfall(){

  var arrBox=$('#content').children('.box');// box对象

  var iBoxW=arrBox.eq(0).innerWidth();// 获取瀑布流块的宽度,注意width(),跟innerWidth()的区别

  var num=Math.floor($(window).width()/iBoxW);//计算窗口能容纳几列

  $('#content').css('width',iBoxW*num);//设置父级宽度

  var arrBoxH=[];//数组,用于存储每列中的所有块框相加的高度

  for(var i=0;i<arrBox.length;i++){//遍历数组瀑布流 块

  var boxH=arrBox.eq(i).innerHeight();//获取当前块的高度

  if(i<num){

   arrBox.eq(i).attr('style','');//防止用户改变窗口大小,到时样式出错

   arrBoxH[i]=boxH; //第一行中的num个块box 先添加进数组arrBoxH

  }else{

   var minH=Math.min.apply(null,arrBoxH);//获取数组arrBoxH中的最小值minH

   var minHIndex=$.inArray(minH,arrBoxH);//使用jquery提供的工具

   arrBox.eq(i).css({'position':'absolute','top':minH,'left':minHIndex*iBoxW});//设置定位

   arrBoxH[minHIndex]+=arrBox.eq(i).innerHeight();//添加后,更新最小列高

  }

  }

 }

 // 判断滚动条是否到底部

 function checkscrollside(){

  var arrBox=$('#content').children('.box');

  //获取最后一个瀑布流块的高度:距离网页顶部(实现未滚到底就开始加载)

  var lastBoxH=arrBox.eq(arrBox.length-1).offset().top;

  var scrollTop=$(window).scrollTop()//获取滚动条卷走的高度

  var documentH=$(window).height();;//显示页面文档的高

  return (lastBoxH<scrollTop+documentH)?true:false;//到达指定高度后 返回true,触发waterfall()函数

 }

 </script>

</head>

<body>

 <div id="content">

 <div class="box"><img src="img/0.jpg" alt=""></div>

 <div class="box"><img src="img/1.jpg" alt=""></div>

 <div class="box"><img src="img/2.jpg" alt=""></div>

 <div class="box"><img src="img/3.jpg" alt=""></div>

 <div class="box"><img src="img/4.jpg" alt=""></div>

 <div class="box"><img src="img/5.jpg" alt=""></div>

 <div class="box"><img src="img/6.jpg" alt=""></div>

 <div class="box"><img src="img/7.jpg" alt=""></div>

 <div class="box"><img src="img/8.jpg" alt=""></div>

 <div class="box"><img src="img/9.jpg" alt=""></div>

 <div class="box"><img src="img/10.jpg" alt=""></div>

 </div>

</body>

</html>

大致思路

 1.先让第一行的浮动

 2.计算第一行的每个块的高度

 3.遍历第一行之后的每一个块,逐个放在最小高度的下面

 4.加载数据插入最后,再重新计算 

注意点

a.原生js 

1.定义了getClassObj()函数用于获取class类的对象,方便调用。考虑了兼容性 getElementsByClassName  

2.定义了getminHIndex()函数用户获取最小值的索引 

3.设置块与块之间的距离最好用padding,这样的话offsetHeight可以直接获取得到高度。如果设置margin则得多加个外边距的距离 

4.代码中设置了定时器加载数据,其实可以省略,只要保证第一次加载的数据能满屏就可以。如果没出现滚动条的话onscroll事件是不会执行到的。也就没办法加载数据了 

5.代码中的计算宽度也可以修改,设计的页面是定宽的瀑布流的话。这里主要是做了响应式的处理 

var arrBox=getClassObj(parentID,childClass);// getClassObj()获取子class的数组

var iBoxW=arrBox[0].offsetWidth;// 获取瀑布流块的宽度

var num=Math.floor(document.documentElement.clientWidth/iBoxW);//计算窗口能容纳几列

oParent.style.width=iBoxW*num+'px';//设置父级宽度 

6.每设置一块位移,都要在列高的数组上增加数值,防止块重叠 

arrBox[i].style.position='absolute';//设置绝对位移

arrBox[i].style.top=minH+'px';

arrBox[i].style.left=minHIndex*iBoxW+'px';//也可以直接获取arrBox[minHIndex].offsetLeft

arrBoxH[minHIndex]+=arrBox[i].offsetHeight;//添加后,更新最小列高 

b.jquery

1.思路是跟js一样的,只是jquery封装了很多方法,让我们简便的就实现了

2.注意width(),跟innerWidth()的区别。前者只能获取宽度值(不包括补白padding) 

css3版本

<!DOCTYPE html>

<html lang="en">

<head>

 <meta charset="UTF-8">

 <title>瀑布流-css3</title>

 <style>

 *{margin:0;padding:0;}

 #content{margin:0 auto;position: relative;width:1200px;column-count:6;-moz-column-count:6;-webkit-column-count:6;}

 .box{padding:10px;width: 180px;}

 .box img{width: 180px;height:auto;display: block;}

 </style>

 <script>

 window.onload=function(){

  //如果数据不够,没出现滚动条,自动加载数据

  var time=setInterval(function(){

  if(checkscrollside()){

   addDate();//插入数据

  }else{

   clearInterval(time);

   window.onscroll=function(){

   if(checkscrollside()){

    addDate();

   };

   }

  }

  },1000) 

 } 

 // 数据插入

 function addDate(){

  var dataInt=['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg','6.jpg','7.jpg','8.jpg'];//模拟数据,也可以是对象

  var oParent = document.getElementById('content');

  for(var i=0;i<dataInt.length;i++){//循环插入数据 

  var oBox=document.createElement('div');

  oBox.className='box';

  oParent.appendChild(oBox);

  var oImg=document.createElement('img');

  oImg.src='./img/'+dataInt[i];

  oBox.appendChild(oImg);

  }

 }

 //获取子class的数组

 function getClassObj(parentID,childClass){

  var oParent=document.getElementById(parentID);

  var allChildObj=oParent.getElementsByTagName('*');//获取父级下的所有子集

  var childObj=[];//创建一个数组 用于收集子元素

  for (var i=0;i<allChildObj.length;i++) {//遍历子元素、判断类别、压入数组

  if (allChildObj[i].className==childClass){

   childObj.push(allChildObj[i]);

  }

  };

  return childObj;

 }

 // 判断滚动条是否到底部

 function checkscrollside(){

  var arrBox=getClassObj("content",'box');

  //获取最后一个瀑布流块的高度:距离网页顶部(实现未滚到底就开始加载)

  var lastBoxH=arrBox[arrBox.length-1].offsetTop;

  var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;//获取滚动条卷走的高度

  var documentH=document.documentElement.clientHeight;//显示页面文档的高

  return (lastBoxH<scrollTop+documentH)?true:false;//到达指定高度后 返回true,触发waterfall()函数

 }

 </script>

</head>

<body>

 <div id="content">

 <div class="box"><img src="img/0.jpg" alt=""></div>

 <div class="box"><img src="img/1.jpg" alt=""></div>

 <div class="box"><img src="img/2.jpg" alt=""></div>

 <div class="box"><img src="img/3.jpg" alt=""></div>

 <div class="box"><img src="img/4.jpg" alt=""></div>

 <div class="box"><img src="img/5.jpg" alt=""></div>

 <div class="box"><img src="img/6.jpg" alt=""></div>

 <div class="box"><img src="img/7.jpg" alt=""></div>

 <div class="box"><img src="img/8.jpg" alt=""></div>

 <div class="box"><img src="img/9.jpg" alt=""></div>

 <div class="box"><img src="img/10.jpg" alt=""></div>

 </div>

</body>

</html>

注意点

1.滚动加载还是得另外加js 

2.加载的数据,是竖向排列的。体验不是很友好 

3.有兼容性问题,Internet Explorer 10 +

以上就是本文的全部内容,希望对大家的学习有所帮助

更多信息请查看网络编程
由于各方面情况的不断调整与变化, 提供的所有考试信息和咨询回复仅供参考,敬请考生以权威部门公布的正式信息和咨询为准!
关于我们 | 联系我们 | 人才招聘 | 网站声明 | 网站帮助 | 非正式的简要咨询 | 简要咨询须知 | 加入群交流 | 手机站点 | 投诉建议
工业和信息化部备案号:滇ICP备2023014141号-1 云南省教育厅备案号:云教ICP备0901021 滇公网安备53010202001879号 人力资源服务许可证:(云)人服证字(2023)第0102001523号
云南网警备案专用图标
联系电话:0871-65317125(9:00—18:00) 获取招聘考试信息及咨询关注公众号:hfpxwx
咨询QQ:526150442(9:00—18:00)版权所有:
云南网警报警专用图标
Baidu
map