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>
posted @ 2022-04-08 18:02  oceanyang  阅读(43)  评论(0编辑  收藏  举报