今天在练习javascript实现瀑布流时遇到了一个看上去非常神奇(实际上无脑)的问题,用js加载十张图片之后的页面效果是这样的:
但是想让它们按高低顺序排列即尽量不留下大量空白空间,于是寻找第一行图片高度的最小值,然后将下一行的图片放在高度最小的图片下面,于是写了下面的程序段:
var BoxHeightArr = [];
for(var j=0;j<ccontent.length;j++) {
if(j<cols)
BoxHeightArr.push(ccontent[j].offsetHeight);
else {
var minHeight = Math.min.apply(null,BoxHeightArr);
var minIndex = getMinHeightLocation(BoxHeightArr,minHeight);
ccontent[j].style.position = "absolute";
ccontent[j].style.top = minHeight+'px';
ccontent[j].style.left = ccontent[minIndex].offsetLeft+'px';
}console.log(j);
}console.log(BoxHeightArr);
但结果却是这样的:
发现问题没有?图片少了,第二行的图片只剩下一张,因为后面的几张图片设置了绝对定位,并且每次都放在了高度最小的图片下面,导致之前的图片被后来的图片覆盖掉,以此警醒大家,同时告诉自己,代码不要乱写,不然很可怕的。
那么解决方法是什么呢?来看一下:
每次要放置下一行的图片时,总是找的高度最小的,如果我们放置好第一张图片之后,将高度最低的那一张图片的高度值修改为与其下面放置的图片的高度和,那么它的高度就不是最小的了,在放置下一张图片时就会重新寻找高度值最小的那一张图片,就不会出现覆盖问题了。
完整代码见下方:
html部分:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="css/style.css" type="text/css" rel="stylesheet"/>
<script src="script/app.js"></script>
</head>
<body>
<div id="container"></div><!--作为容器装载所有的图片-->
</body>
</html>
js部分:
window.onload = function() {
addImages();
imgLocation('container','box');
};
function addImages() {
var container = document.getElementById('container');
for(var j=0;j<5;j++)
for( var i=1;i<11;i++ ) {
var divBox = document.createElement('div');
divBox.setAttribute('class','box');
var divImg = document.createElement('div');
divImg.setAttribute('class','box-img');
var img = document.createElement('img');
var path = "images/" + i + ".jpg";
img.setAttribute('src',path);
divImg.appendChild(img);
divBox.appendChild(divImg);
container.appendChild(divBox);
}
}
// js实现瀑布流布局实现
function imgLocation(parent,content) {
var cParent = document.getElementById(parent);
// 得到所有的box
var ccontent = getChildElement(cParent,content);
// offsetWidth得到物体宽度(包括内部width、边框border和内边距padding)的数值,
var imgWidth = ccontent[0].offsetWidth;
// 一行可以存放图片的个数
var cols = Math.floor(document.documentElement.clientWidth/imgWidth);
cParent.style.cssText = "width:"+imgWidth*cols+"px;margin:0 auto";
// 得到所有box即图片的高度
var BoxHeightArr = [];
for(var j=0;j<ccontent.length;j++) {
if(j<cols) BoxHeightArr.push(ccontent[j].offsetHeight);
else {
var minHeight = Math.min.apply(null,BoxHeightArr);
var minIndex = getMinHeightLocation(BoxHeightArr,minHeight);
ccontent[j].style.position = "absolute";
ccontent[j].style.top = minHeight+'px';
ccontent[j].style.left = ccontent[minIndex].offsetLeft+'px';
// 使最小值改变,不是最小值
BoxHeightArr[minIndex] = BoxHeightArr[minIndex]+ccontent[j].offsetHeight;
}console.log(j);
}console.log(BoxHeightArr);
}
// 得到高度最小的图片的索引位置
function getMinHeightLocation(boxHeightArr,minHeight) {
for(var i=0;i<boxHeightArr.length;i++)
if( boxHeightArr[i]===minHeight ) return i;
}
// 得到容器中所有的子元素
function getChildElement(parent,content) {
var contentArr = [];
var allContent = parent.getElementsByTagName('*');
for(var i=0;i<allContent.length;i++ )
if(allContent[i].className===content)
contentArr.push(allContent[i]);
return contentArr;
}
效果如下:
这是用js插入的图片,页面加载有点慢,不建议使用