概念:瀑布流,又称瀑布流式布局,是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部
特点:
- 琳琅满目:整版以图片为主,大小不一的图片按照一定规律排列
- 唯美:图片的风格以唯美的图片为主
- 操作简单:在浏览网站时只需轻轻滑动一下鼠标滚轮,一切的秒图片便可呈现在眼前
布局优点:
- 有效的降低了界面的复杂度,节省了空间
- 对触屏设备来说,交互方式更符合直觉
- 更高的参与度
瀑布流1
<body>
<div id="water"></div>
<script src="./js/waterfall.js"></script>
<script>
//得到元素
var div = document.getElementById("water");
//图片数组
var imgs = [];
//循环,将图片加载出来
for (var i = 0; i <= 40; i++) {
imgs.push("img/" + i + ".jpg");
}
// 调用函数
creatWaterFall(div, imgs, 220);
</script>
</body>
#water {
position: relative;
width: 90%;
margin: 0 auto;
/* outline: 1px solid; */
}
#water img {
box-shadow: 0 0 10px rgba(0, 0, 0, .5);
border-radius: 10px;
transition: all .5s;
}
/**
* [creatWaterFall description]
* @param {[type]} areaDom [容器]
* @param {[type]} urls [图片的url地址数组]
* @param {[type]} everyWidth [每张图片的宽度]
* @return {[type]} [description]
*/
function creatWaterFall(areaDom,urls,everyWidth){
//有多少列
var colNumber;
//每张图片之间的间隙
var gap;
// 1.创建图片
creatImgDoms();
//2.设置图片的坐标
setImgPosition();
//窗口改变事件 函数防抖
var timer = null;
window.onresize = function() {
if(timer){
clearTimeout(timer);
}
timer = setTimeout(function(){
setImgPosition();
},500);
};
//函数区
/**
* 计算
*
*/
function cal(){
//得到容器的宽度
var containerWidth = parseInt(areaDom.clientWidth);
//列数
colNumber = parseInt(containerWidth / everyWidth);
//剩余空间
var space = containerWidth-colNumber*everyWidth;
//每张图片之间的间距
gap = space / (colNumber + 1);
}
/**
*
* @return {[type]} [创建函数的dom对象]
*/
function creatImgDoms(){
for(var i=0; i<urls.length; i++){
//每张图片的地址数组
var url = urls[i];
//创建一个img对象,并设置相关样式
var img = document.createElement("img");
img.src = url;
img.style.width = everyWidth + "px";
img.style.position = "absolute";
img.onload = function(){
setImgPosition();
};
//将图片放到容器里
areaDom.appendChild(img);
}
}
/**
* 设置每张图片的坐标
*/
function setImgPosition(){
cal();
//存放的是每一列下一个图片的纵坐标
var colY = new Array(colNumber);
colY.fill(0);//将数组的每一项填充为0
for(var i = 0; i < areaDom.children.length; i++){
//得到图片路径
var img = areaDom.children[i];
//找到数组colY中的最小值
var y = Math.min(...colY); // y坐标
var index = colY.indexOf(y); // 第几列
var x = (index + 1) * gap + index * everyWidth;
img.style.left = x + "px";
img.style.top = y + "px";
//更新数组
colY[index] += parseInt(img.height) + gap;
// console.log(img.height);
}
// 找到数组中最大的数字
var height = Math.max(...colY);
areaDom.style.height = height + "px";
}
}
瀑布流2--无限瀑布流
<div class="out"></div>
.out {
margin: 0 auto;
width: 90%;
position: relative;
}
.in {
float: left;
}
img {
margin: 10px;
padding: 10px;
/* border: 1px solid #000; */
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, .5);
}
// 模拟后台数据
var dataStr =
'{"src":["i1.jpg","i2.jpg","i3.jpg","i4.jpg","i5.jpg","i6.jpg","i7.jpg","i8.jpg","i9.jpg","i10.jpg","i11.jpg","i12.jpg","i13.jpg","i14.jpg","i15.jpg"]}';
//将json数据解析成js
var dataObj = JSON.parse(dataStr);
//得到元素
var outDiv = document.querySelector('.out');
// 添加图片
function addDiv_inOut() {
//循环 将图片添加到页面中
for (var i = 0; i < dataObj.src.length; i++) {
var div = document.createElement('div');
div.className = 'in';
div.innerHTML = '<img src="img/' + dataObj.src[i] + '"/>';
outDiv.appendChild(div);
}
}
//构建瀑布
function createWaterFall() {
//求出一行能放多少张图片
//拿到所有的小div
var inDivs = document.querySelectorAll('.in');
//得到视口的宽度 考虑浏览器兼容性问题
// var viewportWidth = document.documentElement.clientWidth || document.body.clientWidth;
var viewportWidth = parseInt(document.documentElement.clientWidth || document.body.clientWidth);
//拿到图片的宽度
var oneWidth = inDivs[0].offsetWidth;
//拿到视口中一行所能放的图片的个数
var num = Math.floor(viewportWidth / oneWidth);
//得到最外层div的宽度
outDiv.style.width = num * oneWidth + "px";
// 用来保存图片的高度
var heightArr = [];
//对每一张图片设置定位,构建瀑布流
for (var j = 0; j < inDivs.length; j++) {
if (j < num) {
//如果是第一行图片则不需要设置定位 但是需要保存高度
heightArr.push(inDivs[j].offsetHeight);
} else {
//如果不是第一行图片,则需要设置定位。根据第一行设置定位
inDivs[j].style.position = 'absolute';
//在高度数组中找到最小高度【当做这张图片的top定位值】
var minHeight = Math.min.apply(null, heightArr);
//在高度数组中,找到最小高度的下标
var minIndex = heightArr.indexOf(minHeight);
//根据找到的下标,然后找到这个最小的div,并获取它的左定位[定位的left值]
var tempLeft = inDivs[minIndex].offsetLeft;
//设置图片的定位
inDivs[j].style.top = minHeight + 'px';
inDivs[j].style.left = tempLeft + 'px';
//将高度数组中最小的高度累加到当前图片的高度上
heightArr[minIndex] = heightArr[minIndex] + inDivs[j].offsetHeight;
}
}
}
addDiv_inOut();
//当页面加载完毕后在执行其他操作
window.onload = function() {
createWaterFall();
}
//计算滚动距离
function judgeMethod() {
var inDivs = document.querySelectorAll('.in');
// 页面滚动的距离
var scrollHeight = document.documentElement.scrollTop || document.body.scrollTop;
//屏幕的距离
var screenClient = document.documentElement.clientHeight;
//最后一个元素的高度
var lastDivHeight = inDivs[inDivs.length - 1].offsetTop;
if (scrollHeight + screenClient > lastDivHeight) {
return true;
}
}
//滚动事件 实现无限瀑布流
window.onscroll = function() {
if (judgeMethod()) {
addDiv_inOut();
createWaterFall();
}
}