这个页面主要通过前端技术中非常流行的瀑布流技术来展示图片,瀑布流技术的原理主要分为两部分:
1.瀑布流的排版
一,先将每张图片的宽度写死固定为某个值,这时每张图片的高度也随之等比例缩小,保证每张图片的宽度都一样。
二,根据浏览器的可视界面的宽度除以每张图片的宽度得出浏览器一行最多能够放几张图片Num,即Num = Math.floor(clientWidth / imgwidth)
三,这时我们先来进行第一行图片的处理,第一行图片的数目即0-NUM之间,将第一行图片直接放到页面中,之后首先我们创建一个ARR数组来存放第一行图片中所有的高度,编曲数组的大小与民大小一致。
四,对于第二行的元素,第一个元素,我们来遍历ARR数组中最小的高度,找到最小高度后我们将这第二行第一个元素放到之前ARR数组中高度最小的元素的下方,将他的离开设置与编曲中元素的offsetLeft属性一致,并将ARR数组中的高度加上此元素的高度,第二个元素也是如此,直到这一行排列完成。这样类似于插空的操作,每次都寻找高度最小的元素来插空保证了瀑布流的紧密。
五,对于后面的几行每一行都能获得之前几行的每一列元素的高度进行循环来寻找最小高度进行插空,直到循环结束。
2.瀑布流的懒加载
瀑布流的瀑布效果则在于它的图片是随着你的滚动条向下拖动而不断加载的,这种效果通过监听滚动条window.onscroll事件来实现,例如每次滚动条向下滚动时,就通过之前的瀑布流排版方式来加载20张图片,这种加载请求的图片既可以是通过AJAX来请求服务器中的网络图片,也可以直接使用本地的IMG图片。
HTML代码
<head>
<style type="text/css">
/*设置每一个瀑布流块*/
#main .pin {
width: 220px;
height: auto;
padding: 15px 0px 0px 15px;
/*上 右 下 左*/
float: left;
}
/*设置每一个瀑布流块中的图像样式*/
#main .pin .box {
width: 220px;
height: auto;
padding: 10px;
background: #FFF;
border: 1px solid #ccc;
box-shadow: 0px 0px 6px #ccc;
/*中间投影*/
border-radius: 5px;
/*圆角*/
}
#main .pin .box img {
width: 200px;
}
</style>
</head>
<body>
<div id="main" style="margin: 0; padding: 0;">
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/0_1.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/1.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/20492_bg.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/3.jpeg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/4.jpeg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/xin3.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/timg.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/0_1.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/1.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/20492_bg.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/3.jpeg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/4.jpeg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/xin3.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/timg.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/0_1.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/1.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/20492_bg.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/3.jpeg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/timg.jpg">
</div>
</div>
<div class="pin">
<div class="box">
<img src="img/20492_bg.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/3.jpeg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/4.jpeg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/xin3.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/timg.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/xin3.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/timg.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/xin3.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/timg.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/xin3.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/timg.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/xin3.jpg">
</div>
</div>
<!--每一个小块-->
<div class="pin">
<div class="box">
<img src="img/timg.jpg">
</div>
</div>
</div>
</body>
JS代码
<meta charset="UTF-8">
<title>瀑布流效果实现</title>
<script src="js/jquery.min.js"></script>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="blog.css" rel="stylesheet" type="text/javascript">
<link href="css/nav.css" rel="stylesheet">
<script type="text/javascript">
var fix = 1;
var num = 20;//一次加载图片的数量20张
window.onload = function() {
//调用函数
waterfall('main', 'pin');
var ajaxState = true;
window.onscroll = function() {
if(checkscrollsite() && ajaxState) {
ajaxState = false;
var oParent = document.getElementById('main');
var aPin = getClassObj(oParent, 'pin');
var lastPinH = aPin[aPin.length - 1].offsetTop + aPin[aPin.length - 1].offsetHeight;
//加入正在加载图标
var loadImg = document.createElement('img');
loadImg.src = './img/load.gif';
loadImg.id = 'loadImg';
oParent.appendChild(loadImg);
loadImg.style.position = 'absolute';
loadImg.style.top = lastPinH + 500 + 'px';
loadImg.style.left = Math.floor(oParent.offsetWidth - loadImg.offsetWidth) + 'px';
//创建父节点
var oParent = document.getElementById('main');
for(var i = num - 19; i <= num; i++) {
//alert(data[i].src);
//创建父级的元素节点
var oPin = document.createElement('div');
oPin.className = 'pin';
oParent.appendChild(oPin);
var oBox = document.createElement('div');
oBox.className = 'box';
oPin.appendChild(oBox);
var oImg = document.createElement('img');
//拼接图片src的url
if(i < 10) {
i = "00" + i;
}
if(i >= 10 && i < 100)
i = "0" + i;
oImg.src = "me/IMG_" + i + ".jpg";
oBox.appendChild(oImg);
}
num = num + 20;
waterfall('main', 'pin');
document.getElementById('main').removeChild(document.getElementById('loadImg'));
ajaxState = true;//状态改为已加载
}
}
}
/**
parent 父级 id
pin 具体瀑布流块,class类名
*/
function waterfall(parent, pin) {
var oParent = document.getElementById(parent);
var aPin = getClassObj(oParent, pin);
var iPinW = aPin[0].offsetWidth;
//计算页面可以放下多少个图片
var num = Math.floor(document.documentElement.clientWidth / iPinW);
//alert(num);
//设置父级居中的样式
oParent.style.cssText = 'width:' + num * iPinW + 'px;margin:0 auto;';
//准备一个数组 来存放每个图片的高度
var compareAarr = [];
for(var i = 0; i < aPin.length; i++) {
//得到每个图片的高度
if(i < num) {
compareAarr[i] = aPin[i].offsetHeight;
} else {
//取数组中的最小高度 compareAarr
var minH = Math.min.apply({}, compareAarr);
//获取最小的key值
var minKey = getMinKey(compareAarr, minH);
//定位超出宽度多的那个
aPin[i].style.position = 'absolute';
//取超出的那个图片的top值
aPin[i].style.top = minH + 'px';
//设置超出那个图片的left值
aPin[i].style.left = aPin[minKey].offsetLeft + 'px';
//超出最后一个在加一 重新计算最低minH
compareAarr[minKey] += aPin[i].offsetHeight;
}
}
}
/**
* 检测根据浏览器的高度加载图片
*/
function checkscrollsite() {
var oParent = document.getElementById('main');
var aPin = getClassObj(oParent, 'pin');
//最后图片的高度
var lastPinH = aPin[aPin.length - 1].offsetTop + Math.floor(aPin[aPin.length - 1].offsetHeight / 2);
//最后滚动条的高度
var srcollTop = document.documentElement.scrollTop || document.body.scrollTop;
//
var documentH = document.documentElement.clientHeight;
//if(lastPinH<srcollTop+documentH){
// return true;
//}else{
// return false;
//}
return lastPinH < srcollTop + documentH ? true : false;
}
/**
获取数组组最小的键值
arr数组
minH最小键值
*/
//定义一个函数 获取数组(compareAarr)中对应的最小的那个高的值(minH)
function getMinKey(arr, minH) {
for(key in arr) {
if(arr[key] == minH) {
return key;
}
}
}
//获取父级parent中所有class为className的子元素集合并返回
function getClassObj(parent, className) {
//4.定义匹配父级下面所有的元素
var obj = parent.getElementsByTagName('*');
//5.定义一个数组
var result = [];
//6.循环obj
for(var i = 0; i < obj.length; i++) {
if(obj[i].className == className) {
//7.pushu进result中
result.push(obj[i]);
}
}
//8
return result;
}
</script>