简介

瀑布流布局是一种很常见的布局方式,他的主要视觉体验为图片元素等宽不等高,图片元素之间的水平排序参差不齐,而且随着滚动条的滚动,数据会进行异步的加载,这样的布局有两个好处,1-有视觉的冲击力,比较好看;2-图片元素能够保持原始比例,不会被拉伸。最终浏览器中看到的效果如下图:

HTML和CSS实现步骤

步骤1:确定html布局,代码(部分)如下

<div id="main">
<div class="box">
<div class="pic">
<img src="img/1.jpg"/>
</div>
</div>
<div class="box">
<div class="pic">
<img src="img/2.jpg"/>
</div>
</div>
</div>

其中class=box的div主要作用是控制定位,class=pic的div的主要作用是实现各种效果,如边框阴影

步骤2:用css实现上图的效果

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

注意:这里我们为什么不直接设置class=pic的margin值作为div之间的间隔,而是在外面又套了一层div呢?因为使用javascript中outerwidth属性能直接算出元素padding+margin+boder的值,而使用margin不能做到这一点。

javascript实现步骤

步骤1:取出所有div[class=box],放到变量var oBoxs中

步骤2:算出屏幕可视区域能容纳div[class=box]的个数,把个数放到var cols中

步骤3:遍历oBoxs,把前cols个div的高度放到变量oBoxsH中

步骤4:找出oBoxsH中的最小值及其索引,把下一个div的top值设置成为oBoxsH中的最小值,left的值设置成为oBoxsH中的最小值及的索引x当前div的宽度

步骤5:更新oBoxsH的最小值

步骤6:判断滚动的临界点,并加载数据

 // 瀑布流主方法
function waterfall(parent,box){
var oParent=document.getElementById(parent);
var oBoxs=getByClass(oParent,box);
var cols = Math.floor(document.documentElement.offsetWidth/oBoxs[0].offsetWidth);
var oBoxsH = [];
for(var i=0;i<oBoxs.length;i++){
if(i<cols){
// 将图片的高度值添加到数组中
oBoxsH.push(oBoxs[i].offsetHeight);
}else{
// 求最小值和最小值的索引
var minBoxH = Math.min.apply(null, oBoxsH);
var idx = getMinhIndex(oBoxsH, minBoxH);
//计算及定义图片出现的位置
oBoxs[i].style.position='absolute';
oBoxs[i].style.left = oBoxs[idx].offsetLeft + 'px';
oBoxs[i].style.top = minBoxH + 'px';
// 改变数组值
oBoxsH[idx] += oBoxs[i].offsetHeight;
}
}
}
// 取出所有class为clsName的元素
function getByClass(parent,clsName){
var boxArr=new Array(),
oElements=parent.getElementsByTagName('*');
for(var i=0;i<oElements.length;i++){
if(oElements[i].className==clsName){
boxArr.push(oElements[i]);
}
}
return boxArr;
} // 求值在数组中的索引,arr接收的是数组,val接收的是判断的值
function getMinhIndex(arr,val){
for(var i=0; i<arr.length; i++) {
if(arr[i] == val) {
return i;
}
}
} // 获取滚动时异步取数据的边界
function checkScrollSide () {
var oBoxs = getByClass(document.getElementById("main"), "box");// 获取所有box
var oEltHeight = Math.floor(oBoxs[oBoxs.length-1].offsetTop + oBoxs[oBoxs.length-1].offsetHeight/2);// 当滚动的高度大小最后一个元素一半时,加载数据
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;// 使用兼容代码
return (oEltHeight < scrollTop + document.documentElement.clientHeight ? true : false)
}

绑定事件,加载数据

var imgData = [{"src":"30.jpg"},{"src":"31.jpg"},{"src":"32.jpg"},{"src":"33.jpg"},{"src":"34.jpg"}];
window.onload=function(){
if(checkScrollSide()) {
loadData();
}
waterfall('main','box'); window.onscroll = function() {
if(checkScrollSide()) {
loadData();
waterfall('main','box');
}
}
}

源代码以及素材下载地址

Github瀑布流工程源代码:https://github.com/sunhaikuo/waterfall.git

使用原生javascript实现瀑布流的更多相关文章

  1. 原生JS实现瀑布流

    浏览网页的时候经常会遇到瀑布流布局的网站.也许有些读者不了解瀑布流.瀑布流,又称瀑布流式布局.是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数 ...

  2. JavaScript——原生js实现瀑布流

    瀑布流介绍及实现原理: 瀑布流是一种页面布局,页面上也有多等宽的块(块就页面内容),每一块都是绝对定位(absolute),每个块排列的方式如下:寻找现在高度最小的列,把该块定位到该列下方.需要知道, ...

  3. JavaScript实现瀑布流

    前端内容: 使用JavaScript和四个div,将照片放入四个div中 <!DOCTYPE html> <html lang="en"> <head ...

  4. javascript实现瀑布流效果(固定宽度)

    HTML代码: <div id="content"> <div class="box"> <div class="img ...

  5. 原生js实现瀑布流效果

    参考此篇:https://segmentfault.com/a/1190000012621936 以下为个人测试中: css: .masonry{ width:100%; } .item{ posit ...

  6. jquery/原生js/css3 实现瀑布流以及下拉底部加载

    思路: style: <style type="text/css"> body,html{ margin:; padding:; } #container{ posit ...

  7. 关于瀑布流的布局原理分析(纯CSS瀑布流与JS瀑布流)

    瀑布流 又称瀑布流式布局,是比较流行的一种网站页面布局方式.即多行等宽元素排列,后面的元素依次添加到其后,等宽不等高,根据图片原比例缩放直至宽度达到我们的要求,依次按照规则放入指定位置. 为什么使用瀑 ...

  8. js瀑布流 原理实现揭秘 javascript 原生实现

    web,js瀑布流揭秘 瀑布流再很久之前流行,可能如我一样入行晚的 ,可能就没有机会去使用.但是这个技术终究是个挺炫酷的东西,花了一个上午来研究,用原生js实现了一个,下面会附上源码,供大家解读. 说 ...

  9. 用原生JavaScript实现图片瀑布流的浏览效果

    学习JS,活跃思维,灵活运用的一个较为典型的学习案例.同一个瀑布流的效果但实现方式却很多,利用递归.冒泡等等手法都可以达到你想要的目的.这次要说的就是利用类似递归来实现此效果的原创方案.此方案个人认为 ...

随机推荐

  1. 奇异值分解(SVD)实例,将不重要的特征值改为0,原X基本保持不变

    >> s = rand(5,7) s = 0.4186  0.8381  0.5028 0.1934 0.6979 0.4966 0.6602 0.8462  0.0196  0.7095 ...

  2. [转]VS 2013 未找到与约束contractname Microsoft.VisualStudio.Utilities.IContentTypeRegistryService...匹配的导出

    前几天,将Visual studio 2013 update 3 升级到了update 5.打开原来的解决方案,出现了 未找到与约束 contractname Microsoft.VisualStud ...

  3. 24.command-executor

    这里先给出题目链接: https://command-executor.hackme.inndy.tw/ 这是一道不错的ctf题,首先说一下考察点: 文件包含读源码 代码分析结合CVE CVE导致的命 ...

  4. oracle开发so easy(一)

    如何让你的程序可以在oracle数据库和sqlserver数据库自由切换? 如何让你从跨数据库开发的不适中解脱出来? 跟我来吧,我们一起开始entity framework的开发之旅.是的,entit ...

  5. rest framework 节流

    一.简单节流示例 所谓节流就是控制用户访问频率,这里分为匿名用户(非登录用户)和登录用户的限制. 匿名用户:根据其 IP 限制其频率 登录用户:IP.用户名都 OK 获取用户请求 IP:request ...

  6. Unity 中动态修改碰撞框(位置,大小,方向)

    在Unity中,玩家处于不同的状态,要求的碰撞框的 位置/大小/方向 会有所改变,怎么动态的修改碰撞框呢? 下面是Capsure Collider(胶囊体)的修改: CapsuleCollider.d ...

  7. (PHP)redis String(字符串)操作

    /** * * String操作 * 字符串操作 * */ //设置键值:成功返回true,否则返回false,键值不存在则新建,否则覆盖 $redis->set('string', 'hell ...

  8. struts2学习笔记——第一个struts2应用配置

    说实在的,随着Java学习的不断深入,特别是Java web框架部分,调bug让人很心累,但是每征服一个bug,内心的成就感也是难以言说的.第一个struts2应用的配置,我昨天折腾了快2个小时,最后 ...

  9. UML——前两章

    前言 软件开发过程中,在生命周期中,我们大都知道要写文档,但是针对这种团队集体完成的事情,如果中间出现了人员流动问题,这时侯有文档仅仅是不够的.为了让大多数开发人员和用户能直观的了解软件开发的进度和流 ...

  10. Ubuntu系统配置的一些要点

    硬盘安装时必须先卸载光驱! 安装时如果是uefi,应该把引导驱动器设为windows所在的硬盘,否则设为整个硬盘..然后就可以用easybcd来设置windows下的引导. unity tweak t ...