瀑布流的实现方式(原生js+jquery+css3)_javascript技巧

前言
 项目需求要弄个瀑布流的页面,用的是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 +

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

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索jquery
, js
, css3
瀑布流
css3瀑布流布局、css3瀑布流 横向排列、css3瀑布流、css3瀑布流布局横向、css3 flex 瀑布流,以便于您获取更多的相关知识。

时间: 2024-08-18 03:17:43

瀑布流的实现方式(原生js+jquery+css3)_javascript技巧的相关文章

九种原生js动画效果_javascript技巧

在做页面中,多数情况下都会遇到页面上做动画效果,我们大部分做动画的时候都是使用框架来做(比如jquery),这里我介绍下如何让通过原生的js来实现像框架一样的动画效果!1.匀速动画效果说明:匀速动画就是动画的效果从开始到结束每次执行的速度都是一致的 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitio

博客侧边栏模块跟随滚动条滑动固定效果的实现方法(js+jquery等)_javascript技巧

当一个页面内容很长的时候,侧边栏栏目可能显得太短,当窗口滑动到靠下的位置,则侧边即失去了展示内容的机会.很多新闻资讯类网站如新浪.网易.CSDN等,会在边栏的右下角以固定的小弹窗形式,以提供更多的内容展示方式,但这并不适合博客和web2.0风格的网站. 现在很多的独立博客和网站如人人网等,都使用了让侧边栏模块随滚动条滑动而位置固定的效果.就是当一个页面很长的时候,设定侧栏内容会跟随滚动条,这种效果适用于评论较多.内容较长的网站.志文工作室调研了几种类似功能的实现方法,摘录之以供参考. 参考一.提

瀑布流的布局方式:360图片搜索美女图片瀑布流布局分析

文章简介:瀑布流的布局方式展现的内容通常是扁平化.琐碎的东西.首先吸引人的应该是图片,并且图片是那种参差不齐的,如果瀑布流中文字过多,会给人很杂乱的感觉,所以瀑布流更适合单纯的图片浏览. 瀑布流的布局方式展现的内容通常是扁平化.琐碎的东西.首先吸引人的应该是图片,并且图片是那种参差不齐的,如果瀑布流中文字过多,会给人很杂乱的感觉,所以瀑布流更适合单纯的图片浏览. 前不久公司上线的项目–360图片搜索的美女秀场频道,就用到了瀑布流的布局方式,这种纯粹的看美女图片的页面用瀑布流还是挺合适的. 以前并

原生的html元素选择器类似jquery选择器_javascript技巧

做前端,需要选择元素,虽说有jquery和各大js库已经帮我造好了轮子,但我想试试自己实现一个,正好项目也不忙,正好加入自己的js文件中,下面是实现代码.用$g("#content .op")这种格式就可以调用,和jquery $()的参数一样: function $findChilds(parentNode, text) { //如果不传入父节点的话,默认为body if(parentNode == undefined) parentNode = document.body; var

前端设计师们最常用的JS代码汇总_javascript技巧

逛社区时看到的文章,我修改调整了内容,如果大家觉得也有帮助 可以收藏下~ HTML5 DOM 选择器 // querySelector() 返回匹配到的第一个元素 var item = document.querySelector('.item'); console.log(item); // querySelectorAll() 返回匹配到的所有元素,是一个nodeList集合 var items = document.querySelectorAll('.item'); console.lo

javascript原生ajax写法分享_javascript技巧

ajax:一种请求数据的方式,不需要刷新整个页面: ajax的技术核心是 XMLHttpRequest 对象: ajax 请求过程:创建 XMLHttpRequest 对象.连接服务器.发送请求.接收响应数据: /** * 得到ajax对象 */ function getajaxHttp() { var xmlHttp; try { //chrome, Firefox, Opera 8.0+, Safari xmlHttp = new XMLHttpRequest(); } catch (e)

适用于javascript开发者的Processing.js入门教程_javascript技巧

这个入门指导是为javascript开发者写的.读这个文档之前,你最好掌握javascript和web开发编程,并还会非常基本的 Processing 知识. 目录:为没有耐心看长篇大论的人准备:         如果你很着急入门,那么你就需要知道以下几点:              1.Processing.js 把 Processing 代码转变成能够在浏览器端运行的javascript代码,实质是通过<canvas>标签来实现绘图的:              2.为了使用它,你的首先下

根据配置文件加载js依赖模块_javascript技巧

要求: 根据下面的配置文件 复制代码 代码如下: module=[ {'name':'jquery','src':'/js/lib/jquery-1.8.3.js'}, {'name':'swfobject','src':'/js/utils/swfobject.js'}, {'name':'fancybox','src':'/js/jquery/jquery.fancybox.js','require':['jquery']}, {'name':'uploadify','src':'/js/u

谈谈impress.js初步理解_javascript技巧

1.对impress.js认识 impress.js 采用 CSS3 与 JavaScript 语言完成的一个可供开发者使用的表现层框架(演示工具). 现在普通开发者可以利用 impress.js 自己开发出类似效果的演示工具,但性能比基于 FLASH 的 Prezi 更优.其功能包括画布的无限旋转与缩放,任意角度放置任意大小的文字,CSS3 3D 效果支持等.同时,也支持传统 PowerPoint 形式的幻灯演示. 目前 impress.js 是基于 webkit 浏览器(Chrome.Saf