前言

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

原生javascript版

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>瀑布流-javascript</title>
<style>
*{margin:;padding:;}
#content{position: relative;margin: 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');
};
}
}
},) }
// 数据插入
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=;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[].offsetWidth;// 获取瀑布流块的宽度
var num=Math.floor(document.documentElement.clientWidth/iBoxW);//计算窗口能容纳几列
oParent.style.width=iBoxW*num+'px';//设置父级宽度
var arrBoxH=[];//数组,用于存储每列中的所有块框相加的高度
for(var i=;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=;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-].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>

demo下载地址:瀑布流(CSS3_js_jquery三种实现方式).rar

注意点

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

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

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

瀑布流的三种实现方式(原生js+jquery+css3)的更多相关文章

  1. js介绍,js三种引入方式,js选择器,js四种调试方式,js操作页面文档DOM(修改文本,修改css样式,修改属性)

    js介绍 js运行编写在浏览器上的脚本语言(外挂,具有逻辑性) 脚本语言:运行在浏览器上的独立的代码块(具有逻辑性) 操作BOM 浏览器对象盒子 操作DOM 文本对象 js三种引入方式 (1)行间式: ...

  2. 通过三个DEMO学会SignalR的三种实现方式

    一.理解SignalR ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信(即:客户端(Web页面)和服务器端可以互相实时的通知消息 ...

  3. Linq to Sql : 三种事务处理方式

    原文:Linq to Sql : 三种事务处理方式 Linq to SQL支持三种事务处理模型:显式本地事务.显式可分发事务.隐式事务.(from  MSDN: 事务 (LINQ to SQL)).M ...

  4. Android平台中实现对XML的三种解析方式

    本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为Android开发中一项重要的技能. 在 ...

  5. C# 三种打印方式含代码

    一:C#代码直接打印pdf文件(打印质保书pdf文件) 引用: 代码注释很详细了. private void btn_pdf_Click(object sender, RoutedEventArgs ...

  6. SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论 SignalR 简单示例 通过三个DEMO学会SignalR的三种实现方式 SignalR推送框架两个项目永久连接通讯使用 SignalR 集线器简单实例2 用SignalR创建实时永久长连接异步网络应用程序

    SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论   异常汇总:http://www ...

  7. python笔记-20 django进阶 (model与form、modelform对比,三种ajax方式的对比,随机验证码,kindeditor)

    一.model深入 1.model的功能 1.1 创建数据库表 1.2 操作数据库表 1.3 数据库的增删改查操作 2.创建数据库表的单表操作 2.1 定义表对象 class xxx(models.M ...

  8. 2019年6月14日 Web框架之Django_07 进阶操作(MTV与MVC、多对多表三种创建方式、前后端传输数据编码格式contentType、ajax、自定义分页器)

    摘要 MTV与MVC 多对多表三种创建方式 ajax ,前后端传输数据编码格式contentType 批量插入数据和自定义分页器 一.MVC与MTV MVC(Model View Controller ...

  9. 通过三个DEMO学会SignalR的三种实现方式 转载https://www.cnblogs.com/zuowj/p/5674615.html

    一.理解SignalR ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信(即:客户端(Web页面)和服务器端可以互相实时的通知消息 ...

随机推荐

  1. JAVA GUI学习 - JPopupMenu鼠标右键菜单组件学习

    public class JPopmenuKnow { public void test() { //为表格添加鼠标右键菜单 JMenuItem jMenuItemFileInfo = new JMe ...

  2. tomcat的JK和JK2

    如今又開始配置JK2,想将Tomcat和apache,但Tomcat上已经不支持对于JK2的开发了,详情请看: Apache-Tomcat mod_jk2 aka JK2 15 November - ...

  3. Objective-C分类 (category)和扩展(Extension)

    1.分类(category) 使用Object-C中的分类,是一种编译时的手段,允许我们通过给一个类添加方法来扩充它(但是通过category不能添加新的实例变量),并且我们不需要访问类中的代码就可以 ...

  4. 180行ruby代码搞定游戏2048

    最今在玩2048这款小游戏,游戏逻辑简单,很适合我这样的对于游戏新入行的人来实现逻辑.于是选择了最拿手的ruby语言来实现这款小游戏的主要逻辑.还是挺简单的,加起来4小时左右搞定. 上代码: requ ...

  5. zoj 1109 zoj 1109 Language of FatMouse(字典树)

    好开心,手动自己按照字典树的思想用c写了一个优化后的trie字典树,就是用链表来代替26个大小的字符数组.完全按照自己按照自己的想法打的,没有参考如何被人的代码.调试了一天,居然最后错在一个小问题上, ...

  6. sql--关于exec和sp_execute

    sql:exec与sp_excutesql的比较 exec与sp_execute都可以执行存储过程和批处理动态sql语句,以下所属均是关于批处理动态sql语句方面. 一.关于输入参数与输出参数 1.使 ...

  7. NSArray 与 NSMutableArray 的排序

    由于集合的使用过程中,经常需要对数组进行排序操作,此博客用于总结对在OC中对数组排序的几种方法 1.当数组中存放的是Foundation框架中提供的对象时,直接使用 compare:方法 如:NSSt ...

  8. iOS 中多线程的简单使用

    iOS中常用的多线程操作有( NSThread, NSOperation GCD ) 为了能更直观的展现多线程操作在SB中做如下的界面布局: 当点击下载的时候从网络上下载图片: - (void)loa ...

  9. 系统变量写在.bash_profile和.bashrc的区别

    今天配置一个代理,正儿八经的把我搞蒙了,不就是export http_porxy=xxx.xxx.xxx.xxx:xxxx 然后重启服务service network restart ,依然连接不了外 ...

  10. mysql server5.6.28 修改数据目录

    1.查看配置文件 mysql --help | grep my.cnf 列出使用哪个配置文件(顺序推) 2.service mysql stop 3.创建新目录 mkdir /data 4.迁移之前的 ...