使用原生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,活跃思维,灵活运用的一个较为典型的学习案例.同一个瀑布流的效果但实现方式却很多,利用递归.冒泡等等手法都可以达到你想要的目的.这次要说的就是利用类似递归来实现此效果的原创方案.此方案个人认为 ...
随机推荐
- python并发编程之多进程1互斥锁与进程间的通信
一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...
- android中如何在系统启动的时候启动自己的service
自定义一个broadcastreciver在去接受系统启动消息,然后在处理的时候启动自己的service即可
- 14.Nginx 文件名逻辑漏洞(CVE-2013-4547)
由于博主在渗透网站时发现现在Nginx搭建的网站是越来越多 所以对Nginx的漏洞来一个全面性的复习,本次从Nginx较早的漏洞开始分析. 2013年底,nginx再次爆出漏洞(CVE-2013-45 ...
- 获取app下载链接
https://itunes.apple.com/cn/app/id1398635899?mt=8 只需要更改其中的id就可以了
- 【IDEA下使用tomcat部署web项目】
1.IDEA下的WEB项目新建就不说了. 2.配置tomcat:file-->settings-->Build,Execution,Deployment-->Application ...
- 更改数据,ExecuteNonQuery()
using (mycon) { mycon.Open(); string MyTime; DateTime dtDate; MyTime = textBox1.Text.ToString(); str ...
- 事务隔离实现并发控制:MySQL系列之十
一.并发访问控制 实现的并发访问的控制技术是基于锁: 锁分为表级锁和行级锁,MyISAM存储引擎不支持行级锁:InnoDB支持表级锁和行级锁: 锁的分类有读锁和写锁,读锁也被称为共享锁,加读锁的时候其 ...
- JMeter - 实时结果 - InfluxDB和Grafana - 第1部分 - 基本设置
概述: 在本文中,我将解释如何使用JMeter + InfluxDB + Grafana获得实时性能测试结果. 请注意,此主题太大,无法涵盖一篇文章中的所有内容.所以,我试图提供与TestAutoma ...
- POJ1013 Counterfeit Dollar
题目来源:http://poj.org/problem?id=1013 题目大意:有12枚硬币,其中有一枚假币.所有钱币的外表都一样,所有真币的重量都一样,假币的重量与真币不同,但我们不知道假币的重量 ...
- Django 03 模板路径、模板变量、常用的过滤器
Django 03 模板路径.模板变量.常用的过滤器 一.模板路径 #1.在每个app下面添加一个templates文件 #2.在项目views.py里面第33行INSTALLED_APPS里面添加上 ...