使用原生javascript实现瀑布流
简介
瀑布流布局是一种很常见的布局方式,他的主要视觉体验为图片元素等宽不等高,图片元素之间的水平排序参差不齐,而且随着滚动条的滚动,数据会进行异步的加载,这样的布局有两个好处,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实现瀑布流的更多相关文章
- 原生JS实现瀑布流
浏览网页的时候经常会遇到瀑布流布局的网站.也许有些读者不了解瀑布流.瀑布流,又称瀑布流式布局.是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数 ...
- JavaScript——原生js实现瀑布流
瀑布流介绍及实现原理: 瀑布流是一种页面布局,页面上也有多等宽的块(块就页面内容),每一块都是绝对定位(absolute),每个块排列的方式如下:寻找现在高度最小的列,把该块定位到该列下方.需要知道, ...
- JavaScript实现瀑布流
前端内容: 使用JavaScript和四个div,将照片放入四个div中 <!DOCTYPE html> <html lang="en"> <head ...
- javascript实现瀑布流效果(固定宽度)
HTML代码: <div id="content"> <div class="box"> <div class="img ...
- 原生js实现瀑布流效果
参考此篇:https://segmentfault.com/a/1190000012621936 以下为个人测试中: css: .masonry{ width:100%; } .item{ posit ...
- jquery/原生js/css3 实现瀑布流以及下拉底部加载
思路: style: <style type="text/css"> body,html{ margin:; padding:; } #container{ posit ...
- 关于瀑布流的布局原理分析(纯CSS瀑布流与JS瀑布流)
瀑布流 又称瀑布流式布局,是比较流行的一种网站页面布局方式.即多行等宽元素排列,后面的元素依次添加到其后,等宽不等高,根据图片原比例缩放直至宽度达到我们的要求,依次按照规则放入指定位置. 为什么使用瀑 ...
- js瀑布流 原理实现揭秘 javascript 原生实现
web,js瀑布流揭秘 瀑布流再很久之前流行,可能如我一样入行晚的 ,可能就没有机会去使用.但是这个技术终究是个挺炫酷的东西,花了一个上午来研究,用原生js实现了一个,下面会附上源码,供大家解读. 说 ...
- 用原生JavaScript实现图片瀑布流的浏览效果
学习JS,活跃思维,灵活运用的一个较为典型的学习案例.同一个瀑布流的效果但实现方式却很多,利用递归.冒泡等等手法都可以达到你想要的目的.这次要说的就是利用类似递归来实现此效果的原创方案.此方案个人认为 ...
随机推荐
- 奇异值分解(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 ...
- [转]VS 2013 未找到与约束contractname Microsoft.VisualStudio.Utilities.IContentTypeRegistryService...匹配的导出
前几天,将Visual studio 2013 update 3 升级到了update 5.打开原来的解决方案,出现了 未找到与约束 contractname Microsoft.VisualStud ...
- 24.command-executor
这里先给出题目链接: https://command-executor.hackme.inndy.tw/ 这是一道不错的ctf题,首先说一下考察点: 文件包含读源码 代码分析结合CVE CVE导致的命 ...
- oracle开发so easy(一)
如何让你的程序可以在oracle数据库和sqlserver数据库自由切换? 如何让你从跨数据库开发的不适中解脱出来? 跟我来吧,我们一起开始entity framework的开发之旅.是的,entit ...
- rest framework 节流
一.简单节流示例 所谓节流就是控制用户访问频率,这里分为匿名用户(非登录用户)和登录用户的限制. 匿名用户:根据其 IP 限制其频率 登录用户:IP.用户名都 OK 获取用户请求 IP:request ...
- Unity 中动态修改碰撞框(位置,大小,方向)
在Unity中,玩家处于不同的状态,要求的碰撞框的 位置/大小/方向 会有所改变,怎么动态的修改碰撞框呢? 下面是Capsure Collider(胶囊体)的修改: CapsuleCollider.d ...
- (PHP)redis String(字符串)操作
/** * * String操作 * 字符串操作 * */ //设置键值:成功返回true,否则返回false,键值不存在则新建,否则覆盖 $redis->set('string', 'hell ...
- struts2学习笔记——第一个struts2应用配置
说实在的,随着Java学习的不断深入,特别是Java web框架部分,调bug让人很心累,但是每征服一个bug,内心的成就感也是难以言说的.第一个struts2应用的配置,我昨天折腾了快2个小时,最后 ...
- UML——前两章
前言 软件开发过程中,在生命周期中,我们大都知道要写文档,但是针对这种团队集体完成的事情,如果中间出现了人员流动问题,这时侯有文档仅仅是不够的.为了让大多数开发人员和用户能直观的了解软件开发的进度和流 ...
- Ubuntu系统配置的一些要点
硬盘安装时必须先卸载光驱! 安装时如果是uefi,应该把引导驱动器设为windows所在的硬盘,否则设为整个硬盘..然后就可以用easybcd来设置windows下的引导. unity tweak t ...