最近闲来无事,对div布局的瀑布流忽然感兴趣了起来,查阅了资料和文件,得到了js原生,jquery,css三种方法的实现方法和原理,一并送给大家,如果是前端入门不久的同学或者想对div有个清晰认识的同学有个了解。希望能帮助到各位。
什么是瀑布流?给大家看看效果
这是我做的瀑布流的效果图,其中的图片内容是我从一个网站上下载的。。。,那么从这张图片就能看到大致来说,
瀑布流就是一些等宽不等高的图片来排列展示的,因为每张图片都不一样大,那么怎么以及我在图片下面展示了各种信息都不一样,以及我在图片下面展示的信息也不一样,所以导致这些展示的框他们的高度都不统一,那么为什么却要求他们之间的宽度都不同意,那么为什么却要要求他们之间的宽度相同呢,这就是瀑布流实现的关键。
那么我们就来一步一步的说明他是怎么实现的,这个过程中也就理解了为什么是这样设计了,首先,我们要在页面中排列所要展示的框的个数,这就是为什么我们要使用等宽的图片了,因为宽度固定我们才能动态的算出不同大小的浏览器能放几张图片来展示
这里我并没有先设置mian的宽度,而是在计算出放置几张图片之后才设置它的宽度,因为我们不仅仅是在展示图片,还有图片下面的内容,所以在计算每张图片的宽度的时候要姜爆锅图片的容器也算进来,而且由于每个展示框之间还有margin值,所以我们计算的时候也要考虑进去,
一、js原生的实现原理和方法:
css代码:
*{
margin:0;
padding:0;
}
#main{
position:relative;
}
.box{
padding:15px 0 0 15px;float:left;
}
.pic{
padding:10px;
border:1px solid #cccccc;
border-radius: 5px;
box-shadow: 0 0 5px #cccccc;
}
.pic img{
width:165px;
height:auto;
}
js原生代码:
window.onload = function () {
waterfall('main','box');
window.onscroll = function () {
var dataJson = {list:[
{'src':'0.jpg'},
{'src':'1.jpg'},
{'src':'2.jpg'},
{'src':'3.jpg'},
{'src':'4.jpg'},
]};
if (checkOnScroll()){
//将当前数据块渲染到页面的尾部
for (var i = 0; i < dataJson.list.length; i++){
var obox = document.createElement('div')
obox.className = 'box'
var oparent = document.getElementById('main')
oparent.appendChild(obox)
var opic = document.createElement('div')
opic.className = 'pic'
obox.appendChild(opic)
var oImg = document.createElement('img')
oImg.src = '../Javascript/images/'+ dataJson.list[i].src
opic.appendChild(oImg)
}
waterfall('main','box');
}
}
}
function waterfall(parent,box) {
//将main下的所有的lcass为box 的元素取出来
var oParent = document.getElementById(parent)
var oBoxs = getByClass(oParent,box);
//console.log(oBoxs.length)
//计算浏览器可是宽度/box的宽度
var oBoxW = oBoxs[0].offsetWidth;
console.log(oBoxW)
var cols = Math.floor(document.documentElement.clientWidth/oBoxW)
console.log(cols)
//设置main的宽度
oParent.style.cssText = 'width:'+ oBoxW * cols +'px;margin:0 auto'
var hArr = [];//存放每一列盒子的高度
for (var i = 0; i< oBoxs.length; i++){
if (i<cols){
hArr.push(oBoxs[i].offsetHeight)
}else{
var minH = Math.min.apply(null,hArr)
//console.log(minH)
var index = getMinHIndex(hArr,minH);
//console.log(index,'index')
oBoxs[i].style.position = 'absolute';
oBoxs[i].style.top = minH+'px';
//oBoxs[i].style.left = oBoxW * index +'px'
oBoxs[i].style.left = oBoxs[index].offsetLeft+'px';
//更新数组
hArr[index] += oBoxs[i].offsetHeight;
}
}
console.log(hArr)
}
function getMinHIndex(arr,value) {
for (var i = 0; i< arr.length;i++){
if (arr[i] == value){
return i
}
}
}
//根据class获取元素
function getByClass(parent,className) {
var boxArr = new Array(),
//用来存储获取到的所有class为box的元素
oElement = parent.getElementsByTagName('*');
for (var i = 0; i <oElement.length; i++ ){
if (oElement[i].className == className){
boxArr.push(oElement[i])
}
}
return boxArr;
}
//检测是否具备了滚动条加载数块的条件
function checkOnScroll() {
var oParent = document.getElementById('main')
var oBoxs = getByClass(oParent,'box');
var lastEleH = oBoxs[oBoxs.length-1].offsetTop + Math.floor(oBoxs[oBoxs.length-1].offsetHeight/2);
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log(scrollTop)
var clientH = document.body.clientHeight || document.documentElement.clientHeight;
return (lastEleH < scrollTop + clientH ? true : false)
}
二、jquery代码的实现方式:
$(window).on('load',function () {
waterfallRule()
$(window).on('scroll',function () {
var dataJson = {list:[
{'src':'0.jpg'},
{'src':'1.jpg'},
{'src':'2.jpg'},
{'src':'3.jpg'},
{'src':'4.jpg'},
]};
if (checkOnScroll){
$.each(dataJson.list,function (key,value) {
var box = $('<div>').addClass('box').appendTo($('#main'))
var pic = $('<div>').addClass('pic').appendTo(box)
$('<img>').attr('src','images/'+ $(value).attr('src')).appendTo(pic)
})
waterfallRule()
}
})
})
function waterfallRule() {
var oboxs = $('#main>div');
var w = $(oboxs).eq(0).outerWidth();
console.log(w)
var cols = Math.floor($(window).width()/w);
console.log(cols)
$('#main').width(cols*w).css('margin','0 auto')
var hArr = []
$(oboxs).each(function (index,value) {
var h = $(oboxs).eq(index).outerHeight();
console.log(h)
if (index<cols){
hArr[index] = h;
}else{
var minH = Math.min.apply(null,hArr);
console.log(minH,'minH')
var minIndex = $.inArray(minH,hArr);
console.log(minIndex);
$(value).css({
'position':'absolute',
'top':minH+'px',
'left':w * minIndex+'px'
})
hArr[minIndex]+=$(oboxs).eq(index).outerHeight();
}
})
}
function checkOnScroll() {
var $lastBox = $('#main>div').last();
var lastBoxDis = $lastBox.offset().top + Math.floor($lastBox.outerHeight()/2);
var scrollTop = $(window).scrollTop();
var documentH = $(window).height();
return (lastBoxDis<scrollTop+documentH)?true:false;
}
三、利用css3的实现方式:
实现原理
多列布局
css3属性column知多少
.container{
-webkit-column-width:160px;
-moz-column-width:160px;
-webkit-column-gap:5px;
-moz-column-gap:5px;
}
/*数据块 砖块*/
.container div{width:160px;
margin:4px 0;}
通过三种方法的实现,希望可以帮助到大家