前几天兴致来了想做一个瀑布流布局的网页,然后就有了各种“神操作”,也在网上看了一些相关的知识点;所以这里对自己这几个小时来一个总结(附源码)
首先来说一下瀑布流的原理吧:瀑布流是许多数据块组成的,可以是图片,可以是div,但是它们都有一个特点,就是等宽不等高,正是因为它等宽不等高,所以如果按部就班的排布的话,才会出现很大的缝隙,特别不好看,说白了瀑布流布局就是充分利用图片之间的空隙来合理的布局,使布局看起来好看。
首先上CSS布局(因为个人喜欢比较美的事物,所以写的比较多……嘿)
*{
margin: 0 ;
padding: 0;
background-color: #333;
}
.container{
position: relative;
width: 1200px;
margin: 20px auto;
}
.container .box{
display: flex;
width: 178px;
margin: 20px 0 30px ;
padding: 5px 0 0 15px;
float: left;
overflow: hidden;
}
.container .box .active{
padding: 10px;
border: 1px solid #cccccc;
box-shadow: 0 0 5px #ccc;
border-radius: 5px;
}
.container .box img{
max-width: 100%;
}
.container .box h2{
margin: 10px 0 0;
padding: 0;
font-size: 20px;
color: white;
}
.container .box p{
margin: 0;
padding: 0 0 10px;
font-size: 16px;
color: floralwhite;
}
这里把HTML代码也附上(这里我是把CSS和JS分开写了)
this is title
You just need to know what to look.
this is title
You just need to know what to look.
this is title
You just need to know what to look.
this is title
You just need to know what to look.
this is title
You just need to know what to look.
this is title
You just need to know what to look.
this is title
You just need to know what to look.
this is title
You just need to know what to look.
没有加入JS就是这副模样
在明白了瀑布流的原理之后现在我们来实现瀑布流及自动加载;首先我们需要平铺第一行,这里我们铺了六张图片,然后就该铺第二行了,那这个待插入的图片应该放在哪个位置呢,我们可以得到每一列的高度,也就是每一列的数据块的高度加起来,得到六个高度的数值,我们算出哪一列高度最小就把待插入的图片插入到那一列的正下方,利用绝对定位定位过去(因为是绝对定位,所以top是距离页面顶部高度),left就是第几列乘以数据块宽度就可以了,如下图,待插入图片应该插入到这里
铺垫了这么多,重点来了!上JS
window.onload=function(){
//开始即调用
waterfall('container','box')
var dataInt = {
"data": [
{"src": '1.png'},{"src": '2.png'},
{"src": '3.jpg'},{"src": '4.png'},
{"src": '5.png'},{"src": '6.png'},
{"src": '7.jpg'},{"src": '8.png'},
]
}
//监听滚动条事件
window.onscroll=function(){
//检查是否具备了滚动条件
if(checkScrollSlide){
var ocontent = document.getElementById('container');
//创建div,并将其加到所有box后面
for(var i = 0; i < dataInt.data.length; i++) {
var obox = document.createElement('div');
obox.className = 'box';
ocontent.appendChild(obox);
var opic = document.createElement('div');
opic.className = 'active';
obox.appendChild(opic);
var oimg = document.createElement('img');
oimg.src = "img/" + dataInt.data[i].src;
opic.appendChild(oimg);
var oh=document.createElement('h2')
oh.innerHTML='this is title'
opic.appendChild(oh);
var op=document.createElement('p')
op.innerHTML='You just need to know what to look.'
opic.appendChild(op)
}
waterfall('container', 'box');
}
}
}
function waterfall(content,box){
//获取大盒子(container)里的所有小盒子(box)
var ocontent=document.getElementById(content);
var oboxs=getByClass(ocontent, box);
//计算整个页面显示的列数(页面宽/box的宽);
var oboxW = oboxs[0].offsetWidth;
//Math.floor 向下取整
var cols = Math.floor(document.documentElement.clientWidth / oboxW);
//设置container的宽度(这里用刚刚计算出来的列数乘盒子的宽度(oboxW * cols)得到的)
ocontent.style.cssText = 'width:' + oboxW * cols + 'px;margin:20 auto';
var heightArr = [];
for(var i = 0; i < oboxs.length; i++) {
if(i < cols) {
// 将前cols张图片的宽度记录到hArr数组中(第一行的高度)
heightArr.push(oboxs[i].offsetHeight);
} else {
//从第二行开始就开始找最小的高度了,决定带插入图片该插入到哪里
//js Math.min.apply()方法,取出数组中的最小值
var minH = Math.min.apply(null, heightArr);
var index = getMinhIndex(heightArr, minH);
// 设置最小高度的图片的style为绝对定位,并设置top和left
oboxs[i].style.position = 'absolute';
oboxs[i].style.top = minH + 'px';
oboxs[i].style.left = oboxs[index].offsetLeft+'px';
heightArr[index] += oboxs[i].offsetHeight;
}
}
}
//返回所有的box盒子
function getByClass(content, cName){
var boxArr = new Array(),
oElements = content.getElementsByTagName('*');
for(var i = 0; i < oElements.length; i++) {
if(oElements[i].className == cName) {
boxArr.push(oElements[i]);
}
}
return boxArr;
}
//获取数组中最小值的下标值
function getMinhIndex(arr, val) {
for(var i in arr) {
if(arr[i] == val) {
return i;
}
}
}
//定义函数检测是否具备了滚动加载数据块的条件
function checkScrollSlide(){
var ocontent = document.getElementById('container');
var oboxs = getByClass(ocontent, 'box');
//获取最后一个box到顶部的距离+ 它自身一半的距离
var lastboxH = oboxs[oboxs.length - 1].offsetTop + Math.floor(oboxs[oboxs.length - 1].offsetHeight / 2);
//获取滚动条滚动距离(为了消除标准模式和怪异模式之间的差别而做的兼容)
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
// 获取window可视化的高度
var height = document.body.clientHeight || document.documentElement.clientHeight;
return(lastboxH < scrollTop + height) ? true : false;
}
代码不复杂,多看几遍多敲几遍就能理解,这里主要讲解一下最后“function checkScrollSlide()”的思想;因为我们这个要实现一直滑一直滑的效果(也就是懒加载),所以我们这里就拿最后一张图片来做对比,通俗理解函数“checkScrollSlide()”的作用就是最后一张图片露出一半了你就应该加载。
然后之前的“waterfall”函数里面的代码实现了页面缩小图片的列数也会相应的改变哦~
这样我们一个基本的瀑布流式布局就完成辣~ !
但是把页面重新恢复之后会挤在一起,这个问题触及到了我的知识盲区,所以如果有懂的小伙伴可以一起交流哦。
(码字不易,能帮到看这篇文章的你就是我前进的动力,嘿咻
( •̀ ω •́ )✧)