一、瀑布流是我們常見的案例,這里主要講述,用jquery的方式實現瀑布流的功能!
引言:我們經常見到很多網站的瀑布流功能,如淘寶、京東這些商品等等..
實現它我們首先考慮幾個問題:1、獲取到數據 2、排列的方式 3、如何實現排列
其實,在瀑布流里有個核心的功能就是用到了絕對定位
我們逐步深入分析:
這是html的布局,css布局可以自己設置,只要保證grid盒子有絕對定位,其父元素有相對定位即可!后面有參考代碼


下面是script部分

這種方式,可以通過for循環按照順序獲取圖片的索引值,然后不斷的更改其css樣式中的top值和left值!
在我們獲取圖片的資源時,有的時候圖片的高度是不一致的,如果一直按照順序排列,最后的圖片顯示,排列不整齊,就會效果不佳!
繼續往下看:
我們可以通過另一種方法,來實現圖片插入當前列最短的一列,可以解決這個問題!
下面我們來主要看一下jquery的代碼:

好了,現在我們已經通過兩種方式解決了瀑布流這個問題,但是我們還有個問題沒有解決,那就是做瀑布流很大的原因是因為圖片的量比較大,我們一個一個寫html是不是有點太low了!
繼續往下看:
下面介紹一種利用引擎模板來獲取json后台的數據的方式,實現這個問題!
1、我們只需要搭建一個html盒子即可!

2、盒子搭建好了,數據要獲取啊,就靠它!

3、這是兩個js庫,在網上可下載到!

4、下面是具體的js部分,需要仔細分析了!
主要包括,調用搜索引擎模板里獲取到的內容,綁定函數,轉換成jquery對象!

這一部分主要包括:通過ajax向json請求數據

這一部分主要包括:遍歷函數,進行尋找最短的列排列格子!

還有這一些,也是第四部分:

最后一步是:滾動的函數,這一部分建議使用console.log在后台驗證一下,更容易理解!

雖然最后一種辦法麻煩,但是這一次完成,我們就可以使用很多次,並且自動獲取很多數據!
下面給大家附上原碼,大家好好測試一下,不要忘記更改圖片和路徑哦!
第一種方法原碼:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
body{
background-color: #ccc;
}
.waterfall{
width: 790px;
/*height: 1000px;*/
/*border: 1px solid red;*/
margin: 0 auto;
position: relative;
}
.grid{
position: absolute;
width: 230px;
background-color: white;
padding: 10px;
border-radius: 15px;
}
.grid img{
width: 230px;
}
</style>
</head>
<body>
<div class="waterfall">
<div class="grid">
<img src="images/0.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/1.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/2.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/3.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/4.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/5.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/6.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/7.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/8.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/9.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/10.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/11.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/12.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
</div>
<script type="text/javascript" src="js/jquery-1.12.3.min.js"></script>
<script type="text/javascript">
window.onload = function(){
//得到所有的grid
$grids = $(".grid");
//
$grids.each(function(){
var sum = 0;
//遍歷它上面的人的總高度
for(var i = $(this).index() - 3 ; i >= 0 ; i-=3){
sum += $grids.eq(i).outerHeight() + 20;
}
console.log($(this).index());
$(this).css({
"top" : sum,
"left" : ($(this).index() % 3) * 270
})
});
}
</script>
</body>
</html>
第二種方法原碼:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
body{
background-color: #ccc;
}
.waterfall{
width: 790px;
margin: 0 auto;
position: relative;
}
.grid{
position: absolute;
width: 230px;
background-color: white;
padding: 10px;
border-radius: 15px;
}
.grid img{
width: 230px;
}
</style>
</head>
<body>
<h3>瀑布流的算法2,看哪個列最矮,插入在哪個列</h3>
<div class="waterfall">
<div class="grid">
<img src="images/0.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/1.png" alt="" />
<p>內容內容內容內容內容內容內內容內容內容內內容內容內容內內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/2.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/3.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/4.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/5.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/6.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/7.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/8.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/9.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/10.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/11.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
<div class="grid">
<img src="images/12.png" alt="" />
<p>內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容</p>
</div>
</div>
<script type="text/javascript" src="js/jquery-1.12.3.min.js"></script>
<script type="text/javascript" src="js/underscore.js"></script>
<script type="text/javascript">
window.onload = function(){
//每個格格不一定往自己序號%3這個列插入,看哪個列目前最矮,插在哪里=
//得到所有的grid
$grids = $(".grid");
//用一個數組存儲當前三個列的總高度
var colHeight = [0,0,0];
// console.log(colHeight);
// 遍歷小格格
$grids.each(function(){
//找一下當前的最短列是誰
var minValue = _.min(colHeight); //colHeight里面的最小的值!
//看一下最短列出現在index幾的位置上
var minIndex = _.indexOf(colHeight,minValue);//最短的值的下標
// console.log(minIndex);
$(this).css({
"top" : minValue ,
"left" : minIndex * 270
});
colHeight[minIndex] += $(this).outerHeight() + 20;
// console.log(colHeight[minIndex]);
})
}
</script>
</body>
</html>
第三種方法原碼:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
body{
background-color: #ccc;
}
.waterfall{
width: 790px;
margin: 0 auto;
position: relative;
}
.grid{
position: absolute;
width: 230px;
background-color: white;
padding: 10px;
border-radius: 15px;
}
.grid img{
width: 230px;
}
.grid .title{
font-weight: bold;
font-size: 18px;
line-height: 32px;
}
.grid .neirong{
line-height: 150%;
font-size: 14px;
margin-bottom: 20px;
}
.grid .zuozhe{
float: right;
color:orange;
font-size: 12px;
}
.loading{
margin: 0 auto;
width: 400px;
line-height: 30px;
text-align: center;
font-size: 14px;
background-color: gold;
color:white;
}
</style>
</head>
<body>
<div class="waterfall" id="waterfall">
</div>
<div class="loading">
正在加載...
</div>
<script type="text/template" id="grid_template">
<div class="grid">
<img src="<%=imgurl%>" alt="" />
<p class="title"><%=title%></p>
<p class="neirong"><%=content%></p>
<p class="zuozhe"><%=author%></p>
</div>
</script>
<script type="text/javascript" src="js/jquery-1.12.3.min.js"></script>
<script type="text/javascript" src="js/underscore.js"></script>
<script type="text/javascript">
// 定義變量和對象
// 獲取引擎模板中發的內容,使用jquery轉化成字符串
var templateString = $("#grid_template").html();
// 把轉化后的字符串綁定在compileFunction函數上!
var compileFunction = _.template(templateString);//_.template()返回的是一個函數!
// console.log(typeof(compileFunction)); //function
//轉換成jquery對象,為了后面使用jquery的方法
var $waterfall = $("#waterfall");
var $loading = $(".loading");
//三列瀑布流,每列的總高度
var colHeight = [0,0,0];
// 這是三列的高度數組,與里面的數值無關,表示index的順序
// console.log(colHeight);
// 獲取數據
//信號量
var page = 1;
getJSONandRender(page);
function getJSONandRender(page){
// 為了增加用戶體驗
$loading.show();
//發出ajax請求
$.get("json/json" + page + ".txt",function(data){ //輸出字符串
//轉為對象
var dataObj = eval("(" + data + ")"); //解析ajax數據,轉換成對象!
//沒有更多數據了
// dataObj.news.length來自后台json
if(dataObj.news.length == 0){
$loading.show().html("沒有更多了");
return; //在這里截止后,lock也會截止
}
// 遍歷函數,動態獲取下標值根據絕對定位的位置進行排列!
_.each(dataObj.news,function(dictionary){ //每遍歷一次,執行一次函數!
//這是系統內置構造函數
var image = new Image(); //實例化一個對象分配內存空間
// 當對象被實例化后,構造函數會立即執行它所包含的任何代碼
image.src = dictionary.imgurl;
//我們現在給image轉為jQuery對象,然后綁定事件
$(image).load(function(){
// console.log(dictionary.imgurl + "加載完畢");
var domString = compileFunction(dictionary);
// console.log(typeof(domString));
var $grid = $(domString);
$waterfall.append($grid);
//根據瀑布流算法,設置它的left、top
// 最小值
minValue = _.min(colHeight);
// 最小值的位置!
minIndex = _.indexOf(colHeight,minValue);
$grid.css({
"top" : minValue,
"left" : minIndex * 270
});
//改變總列高數組的值
colHeight[minIndex] += $grid.outerHeight() + 10;
//讓大盒子根據最高的列設置高度
$waterfall.css("height",_.max(colHeight));
//隱藏loading文本
$loading.hide();
});
});
lock = true;
});
}
var lock = true;
//監聽滾動
$(window).scroll(function(){
if(!lock) return;
var rate = $(window).scrollTop() / ($(document).height() - $(window).height());
if(rate >= 0.7){
page ++;
getJSONandRender(page);
lock = false;
}
})
</script>
</body>
</html>
