js实现瀑布流排序加载效果
瀑布流是一种比较适用于相册或图片管理站点,像现在百度图片都使用瀑布流效果,下面我来介绍向种实现 瀑布流实例。
方法一、js实现瀑布流排序
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta charset="utf-8" />
<title>js实现瀑布流排序 http://www.3aj.cn/article/8449.html</title>
<style type="text/css">
*{ margin:0; padding:0;}
body { font:12px/1.8 Arial; color:#666;}
h1.tit-h1 { font-size:38px; text-align:center; margin:30px 0 15px; color:#f60;}
.go-back{ text-align:center; border-top:1px dashed #ccc; padding:10px; margin-top:20px; font-size:40px;}
li{ list-style:none;}
.wrapper {padding:50px;}
</style>
<link href="style.css" rel="stylesheet" type="text/css" />
<body>
<div class="wrapper">
<div id="wrap" class="wrap active">
<script language="javascript">
var $id = function(o){ return document.getElementById(o) || o};
for (i=0; i<30; i++) {
var src = Math.floor(Math.random()*100);
if(src<10){src="0"+src}
if(src<100){src="0"+src}
var div = document.createElement("div");
div.className = "mode popup_in";
div.innerHTML = "<p class='pic'><a href='#'><img src=http://www.3aj.cn/common/image/logo.png style='height:"+"auto"+";'/></a></p><h3 class='tit'><span><a href='#'>"+src+".jpg</a></span></h3>";
div.style.top = 0;
div.style.left = 0;
document.getElementById("wrap").appendChild(div);
}
</script>
</div>
<script type="text/javascript">
var warpWidth = 220; //格子宽度
var margin = 14; //格子间距
function postPosition(el,childTagName) {
var h = []; //记录每列的高度
var box = el.getElementsByTagName(childTagName);
var minH = box[0].offsetHeight,
boxW = box[0].offsetWidth+margin;
n = document.documentElement.offsetWidth / boxW | 0; //计算页面能排下多少Pin
el.style.width = n * boxW - margin + "px";
el.style.visibility = "visible";
for (var i = 0; i < box.length; i++) {//排序算法,有待完善
boxh = box[i].offsetHeight; //获取每个Pin的高度
if (i < n) { //第一行特殊处理
h[i] = boxh;
box[i].style.top = 0 + 'px';
box[i].style.left = (i * boxW) + 'px';
} else {
minH = Array.min(h); //取得各列累计高度最低的一列
minKey = getarraykey(h, minH);
h[minKey] += boxh+margin ; //加上新高度后更新高度值
el.style.height = h[minKey] +"px";
box[i].style.top = minH+margin + 'px';
box[i].style.left = (minKey * boxW) + 'px';
}
}
for(var i = 0; i < box.length; i++) {
box[i].style.visibility = "visible"; //定位完毕后显示新增节点
}
}
Array.min=function(array) {
return Math.min.apply(Math,array);
}
/* 返回数组中某一值的对应项数 */
function getarraykey(s, v) {
for(k in s) {
if(s[k] == v) {
return k;
}
}
}
window.onload = function() {
postPosition($id("wrap"),"div");
};
var re;
window.onresize = function() {
clearTimeout(re);
re = setTimeout(resize,100);
};
function resize(){
$id("wrap").className = "wrap active";
postPosition($id("wrap"),"div");
}
</script>
<div id="aaa1" style="display:none;position: fixed;width:400px;height:200px;background:#000;color:#fff;top:30%;left:50%"></div>
</div>
</body>
</html>
实例二、js基于多栏列表瀑布流布局
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta charset="utf-8" />
<title>js基于多栏列表瀑布流布局demo</title>
<style type="text/css">
*{ margin:0; padding:0;}
body { font:12px/1.8 Arial; color:#666;}
h1.tit-h1 { font-size:38px; text-align:center; margin:30px 0 15px; color:#f60;}
.go-back{ text-align:center; border-top:1px dashed #ccc; padding:10px; margin-top:20px; font-size:40px;}
li{ list-style:none;}
.wrapper {padding:50px;}
</style>
<style>
body {
background-color: #eee;
font-size: 84%;
text-align: justify;
}
.column {
display: inline-block;
vertical-align: top;
}
.pic_a {
display: block;
padding: 5px;
margin-bottom: 10px;
border: 1px solid #ccc;
background-color: #fff;
text-decoration: none;
}
.pic_a img {
display: block;
margin: 0 auto 5px;
border: 0;
vertical-align: bottom;
}
.pic_a strong {
color: #333;
}
</style>
<body>
<div class="wrapper">
<div id="container"></div>
<script>
var waterFall = {
container: document.getElementById("container"),
columnNumber: 1,
columnWidth: 210,
// P_001.jpg ~ P_160.jpg
rootImage: "http://cued.xunlei.com/demos/publ/img/",
indexImage: 0,
scrollTop: document.documentElement.scrollTop || document.body.scrollTop,
detectLeft: 0,
loadFinish: false,
// 返回固定格式的图片名
getIndex: function() {
var index = this.indexImage;
if (index < 10) {
index = "00" + index;
} else if (index < 100) {
index = "0" + index;
}
return index;
},
// 是否滚动载入的检测
appendDetect: function() {
var start = 0;
for (start; start < this.columnNumber; start++) {
var eleColumn = document.getElementById("waterFallColumn_" + start);
if (eleColumn && !this.loadFinish) {
if (eleColumn.offsetTop + eleColumn.clientHeight < this.scrollTop + (window.innerHeight || document.documentElement.clientHeight)) {
this.append(eleColumn);
}
}
}
return this;
},
// 滚动载入
append: function(column) {
this.indexImage += 1;
var html = '', index = this.getIndex(), imgUrl = this.rootImage + "P_" + index + ".jpg";
// 图片尺寸
var aEle = document.createElement("a");
aEle.href = "###";
aEle.className = "pic_a";
aEle.innerHTML = '<img src="'+ imgUrl +'" /><strong>'+ index +'</strong>';
column.appendChild(aEle);
if (index >= 160) {
//alert("图片加载光光了!");
this.loadFinish = true;
}
return this;
},
// 页面加载初始创建
create: function() {
this.columnNumber = Math.floor(document.body.clientWidth / this.columnWidth);
var start = 0, htmlColumn = '', self = this;
for (start; start < this.columnNumber; start+=1) {
htmlColumn = htmlColumn + '<span id="waterFallColumn_'+ start +'" class="column" style="width:'+ this.columnWidth +'px;">'+
function() {
var html = '', i = 0;
for (i=0; i<5; i+=1) {
self.indexImage = start + self.columnNumber * i;
var index = self.getIndex();
html = html + '<a href="###" class="pic_a"><img src="'+ self.rootImage + "P_" + index +'.jpg" /><strong>'+ index +'</strong></a>';
}
return html;
}() + '</span> ';
}
htmlColumn += '<span id="waterFallDetect" class="column" style="width:'+ this.columnWidth +'px;"></span>';
this.container.innerHTML = htmlColumn;
this.detectLeft = document.getElementById("waterFallDetect").offsetLeft;
return this;
},
refresh: function() {
var arrHtml = [], arrTemp = [], htmlAll = '', start = 0, maxLength = 0;
for (start; start < this.columnNumber; start+=1) {
var arrColumn = document.getElementById("waterFallColumn_" + start).innerHTML.match(/<a(?:.|n|r|s)*?a>/gi);
if (arrColumn) {
maxLength = Math.max(maxLength, arrColumn.length);
// arrTemp是一个二维数组
arrTemp.push(arrColumn);
}
}
// 需要重新排序
var lengthStart, arrStart;
for (lengthStart = 0; lengthStart<maxLength; lengthStart++) {
for (arrStart = 0; arrStart<this.columnNumber; arrStart++) {
if (arrTemp[arrStart][lengthStart]) {
arrHtml.push(arrTemp[arrStart][lengthStart]);
}
}
}
if (arrHtml && arrHtml.length !== 0) {
// 新栏个数
this.columnNumber = Math.floor(document.body.clientWidth / this.columnWidth);
// 计算每列的行数
// 向下取整
var line = Math.floor(arrHtml.length / this.columnNumber);
// 重新组装HTML
var newStart = 0, htmlColumn = '', self = this;
for (newStart; newStart < this.columnNumber; newStart+=1) {
htmlColumn = htmlColumn + '<span id="waterFallColumn_'+ newStart +'" class="column" style="width:'+ this.columnWidth +'px;">'+
function() {
var html = '', i = 0;
for (i=0; i<line; i+=1) {
html += arrHtml[newStart + self.columnNumber * i];
}
// 是否补足余数
html = html + (arrHtml[newStart + self.columnNumber * line] || '');
return html;
}() + '</span> ';
}
htmlColumn += '<span id="waterFallDetect" class="column" style="width:'+ this.columnWidth +'px;"></span>';
this.container.innerHTML = htmlColumn;
this.detectLeft = document.getElementById("waterFallDetect").offsetLeft;
// 检测
this.appendDetect();
}
return this;
},
// 滚动加载
scroll: function() {
var self = this;
window.onscroll = function() {
// 为提高性能,滚动前后距离大于100像素再处理
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if (!this.loadFinish && Math.abs(scrollTop - self.scrollTop) > 100) {
self.scrollTop = scrollTop;
self.appendDetect();
}
};
return this;
},
// 浏览器窗口大小变换
resize: function() {
var self = this;
window.onresize = function() {
var eleDetect = document.getElementById("waterFallDetect"), detectLeft = eleDetect && eleDetect.offsetLeft;
if (detectLeft && Math.abs(detectLeft - self.detectLeft) > 50) {
// 检测标签偏移异常,认为布局要改变
self.refresh();
}
};
return this;
},
init: function() {
if (this.container) {
this.create().scroll().resize();
}
}
};
waterFall.init();
</script>
</div>
</body>
</html>