小程序實現瀑布流效果,和web頁面差不多,都要經過以下步驟:
1)、加載圖片,獲取圖片的寬高度;
2)、根據頁面需要顯示幾列計算每列的寬度;
3)、根據圖片真實寬度和每列的寬度比,計算出圖片需要顯示的高度;
4)、重新對圖片進行定位
前端精品教程:百度網盤下載
1、web頁面瀑布流效果,先看效果圖(瀑布流+無限滾動加載):
頁面代碼:
前端精品教程:百度網盤下載
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
<!DOCTYPE html>
<html lang=
"en"
>
<head>
<meta charset=
"UTF-8"
>
<meta charset=
'utf-8′> <!--聲明文檔使用的字符編碼-->
<title>瀑布流_左浮動</title>
<style type="text/css">
*{margin:0;padding:0;}
.container {
width: 1200px; height: auto; margin: 50px auto;
position: relative;
}
.box{
padding: 5px; box-shadow: 0 0 10px purple; border-radius: 5px;
float: left; margin: 10px;
}
.box img { width: 200px; height: auto; }
</style>
</head>
<body>
<div class="container">
<div class="box"><img src="../img/0.jpg"/></div>
<div class="box"><img src="../img/1.jpg"/></div>
<div class="box"><img src="../img/2.jpg"/></div>
<div class="box"><img src="../img/3.jpg"/></div>
<div class="box"><img src="../img/4.jpg"/></div>
<div class="box"><img src="../img/5.jpg"/></div>
<div class="box"><img src="../img/6.jpg"/></div>
<div class="box"><img src="../img/7.jpg"/></div>
<div class="box"><img src="../img/8.jpg"/></div>
<div class="box"><img src="../img/9.jpg"/></div>
<div class="box"><img src="../img/10.jpg"/></div>
<div class="box"><img src="../img/11.jpg"/></div>
<div class="box"><img src="../img/12.jpg"/></div>
<div class="box"><img src="../img/13.jpg"/></div>
<div class="box"><img src="../img/14.jpg"/></div>
<div class="box"><img src="../img/15.jpg"/></div>
<div class="box"><img src="../img/16.jpg"/></div>
</div>
<script type="text/javascript">
var boxsHeight = []; //盒子高度存儲數組
var boxWidth = 230, boxHeight = 230;
window.onload = function(){
var boxs = document.getElementsByClassName('
box
');
var cols = Math.floor(1200.0/boxWidth); //最多幾列
//offsetWidth: 包括元素的內容寬度+padding+border寬度
//存儲第一行的每個盒子的高度到數組里面
for (var i = 0; i < cols; i++){
var obj = boxs[i]; //元素節點
if (i < cols){
boxsHeight.push(obj.offsetHeight);
}
}
updateBoxFrame(cols); //從第二行開始更新元素的位置
window.onscroll = pageScroll; //設置頁面滾動監聽函數
pageScroll(); //先調用一次
}
//獲取數組中最小值的索引
function getMinHeightIndex(arr){
var minHeight = Math.min.apply(null, arr);
for (var i = 0; i < arr.length; i++){
if (arr[i] == minHeight){
return i;
}
}
}
//監聽頁面滾動
function pageScroll(){
var parentEle = document.getElementsByClassName('
container
')[0];
var subEleCount = parentEle.childElementCount; //子元素個數
var lastBox = parentEle.lastElementChild; //最后一個元素
//判斷是否滾動到底部
var doc = document.documentElement||document.body;
console.log('
滾動監聽
', doc.scrollTop+",", lastBox.offsetTop+", " + doc.clientHeight);
if (doc.scrollTop+doc.clientHeight > lastBox.offsetTop){
//表示該新添加元素了
addBox();
//更新新添加元素的位置
updateBoxFrame(subEleCount);
}
}
//新添加子元素
function addBox(){
var parentEle = document.getElementsByClassName('
container
')[0];
var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
for (var i = 0; i < arr.length; i++){
var index = parseInt(Math.random()*100%arr.length);
var imgNum = arr[index];
var div = document.createElement('
div
');
div.setAttribute('
class
', '
box
');
div.innerHTML = '
<img src=
"../img/' + imgNum + '.jpg"
/>
'
parentEle.appendChild(div);
arr.splice(index, 1)
}
}
//更新新添加元素的位置
function updateBoxFrame(startIndex){
var boxs = document.getElementsByClassName('
box
');
for (var i = startIndex; i < boxs.length; i++){
var obj = boxs[i];
//獲取數組中最小高度的索引
var minHeightIndex = getMinHeightIndex(boxsHeight);
// console.log(boxsHeight);
// console.log(minHeightIndex + ", " +boxsHeight[minHeightIndex]);
var boxTop = boxsHeight[minHeightIndex] + 20;
var boxLeft = minHeightIndex * boxWidth;
console.log(i + '
, boxTop:
' + boxTop + ", boxLeft: " + boxLeft);
//設置元素的定位樣式
obj.style = '
position: absolute; top:' + boxTop +
"px;left:"
+ boxLeft+
"px"
;
boxsHeight[minHeightIndex] = boxTop + obj.offsetHeight;
}
}
</script>
</body>
</html>
|
2、小程序實現瀑布流,大致流程差不多。只不過小程序的圖片的寬高度的獲取沒有web頁面那么方便。
大概實現過程:1)、獲取圖片數據,頁面渲染;
2)、給圖片綁定加載load事件,存儲每個圖片的寬高度;
3)、計算每個圖片的定位,重新渲染
先看小程序的效果圖(瀑布流+無限循環加載):
前端精品教程:百度網盤下載
wxml頁面代碼:
1
2
3
|
<scroll-view class=
'main'
scroll-y=
'true'
style=
"height:{{windowHeight}}px"
bindscrolltolower=
'loadMoreImages'
>
<image wx:
for
=
'{{dataList}}'
wx:key=
'item'
src=
'{{item.src}}'
style=
'position: absolute; top: {{item.top}}px; left: {{item.left}}px; width: {{imgWidth}}px; height: {{item.height}}px'
bindload=
'loadImage'
data-index=
'{{index}}'
bindtap=
'previewImg'
/>
</scroll-view>
|
js頁面代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
// pages/discover/waterfall_flow/waterfall_flow.js
Page({
/**
* 頁面的初始數據
*/
data: {
dataList: [],
//數據源
windowWidth: 0,
//頁面視圖寬度
windowHeight: 0,
//視圖高度
imgMargin: 6,
//圖片邊距: 單位px
imgWidth: 0,
//圖片寬度: 單位px
topArr: [0, 0],
//存儲每列的累積top
},
/**
* 生命周期函數--監聽頁面加載
*/
onLoad:
function
(options) {
wx.showLoading({
title:
'加載中...'
,
})
var
that =
this
;
//獲取頁面寬高度
wx.getSystemInfo({
success:
function
(res) {
console.log(res)
var
windowWidth = res.windowWidth;
var
imgMargin = that.data.imgMargin;
//兩列,每列的圖片寬度
var
imgWidth = (windowWidth - imgMargin * 3) / 2;
that.setData({
windowWidth: windowWidth,
windowHeight: res.windowHeight,
imgWidth: imgWidth
},
function
() {
that.loadMoreImages();
//初始化數據
});
},
})
},
//加載圖片
loadImage:
function
(e) {
var
index = e.currentTarget.dataset.index;
//圖片所在索引
var
imgW = e.detail.width, imgH = e.detail.height;
//圖片實際寬度和高度
var
imgWidth =
this
.data.imgWidth;
//圖片寬度
var
imgScaleH = imgWidth / imgW * imgH;
//計算圖片應該顯示的高度
var
dataList =
this
.data.dataList;
var
margin =
this
.data.imgMargin;
//圖片間距
//第一列的累積top,和第二列的累積top
var
firtColH =
this
.data.topArr[0], secondColH =
this
.data.topArr[1];
var
obj = dataList[index];
obj.height = imgScaleH;
if
(firtColH < secondColH) {
//表示新圖片應該放到第一列
obj.left = margin;
obj.top = firtColH + margin;
firtColH += margin + obj.height;
}
else
{
//放到第二列
obj.left = margin * 2 + imgWidth;
obj.top = secondColH + margin;
secondColH += margin + obj.height;
}
this
.setData({
dataList: dataList,
topArr: [firtColH, secondColH],
});
},
//加載更多圖片
loadMoreImages:
function
() {
var
imgs = [
];
var
tmpArr = [];
for
(let i = 0; i < 22; i++) {
var
index = parseInt(Math.random() * 100) % imgs.length;
var
obj = {
src: imgs[index],
height: 0,
top: 0,
left: 0,
}
tmpArr.push(obj);
imgs.splice(index, 1);
}
var
dataList =
this
.data.dataList.concat(tmpArr)
this
.setData({ dataList: dataList },
function
(){
wx.hideLoading()
});
},
/**預覽圖片 */
previewImg:
function
(e) {
var
index = e.currentTarget.dataset.index;
var
dataList =
this
.data.dataList;
var
currentSrc = dataList[index].src;
// var srcArr = dataList.map(function (item) {
// return item.src;
// });
wx.previewImage({
urls: [currentSrc],
})
},
})
|
wxss頁面代碼:
1
2
3
4
|
.main{ width: 100%; height: 100%; position: relative; }
.main image {
box-shadow: 0 0 10rpx red; border-radius: 8rpx;
}
|
DEMO下載:https://github.com/xiaotanit/Tan_HtmlDemo
小程序瀑布流頁面地址:https://github.com/xiaotanit/Tan_HtmlDemo/tree/master/wxMini/pages/discover/waterfall_flow