个人记录用
由于涉及动态加载,所以纯css方法column-count等不太适用,需要js
两列瀑布流,每一项的宽度固定,高度不确定,每一项由两部分组成:高度不确定的图片和高度确定的内容区
思路:计算出每一项的图片的高度+固定内容高度得出项的总高,瀑布流的两列为两个list,哪个list的高度更低,就把当前项push进去,统计两个list的高度。
计算图片高度,使用img的bindload事件(如果能够从后端获取到图片的宽高可跳过此步)
<view style="display: none;" id="hidden-imgs">
<image wx:for="{{ hiddenImgs }}" wx:key="index" data-id="{{ item.id }}" src="{{ item.imgUrl[0] }}" bindload="onImageLoad" class="hidden-img" mode="widthFix" />
</view>
获取到数据后将其单独存放在一个hiddenImgs数组中使其添加到dom而不显示,待图片加载完后会自动触发onImageLoad事件返回图片高度。
得到图片宽高为oImgW和oImgH,以iPhoneX为例,假设两列中每一项宽度为300rpx即150px
data: {
list: [],
listLeft: [],
listRight: []
}
otherData: {
itemOthersHeight: 100, // px 列表每一项除了图片之外的元素的高度
leftHeight: 0, // 两列中左list的总高度
rightHeight: 0 // 两列中右list的总高度
},
onLoad() {
this.getList();
},
getList() {
// ...
this.setData({
hiddenImgs: res.result.list,
list: res.result.list,
loadAll: res.result.totalCount <= 10 ? true : false
})
},
onImageLoad(e) {
const vm = this;
let { listLeft, listRight, list } = vm.data;
let { leftHeight, rightHeight, itemOthersHeight } = vm.otherData;
const imgId = e.currentTarget.dataset.id;
const oImgH = e.detail.height;
const oImgW = e.detail.width;
const realHeight = 150 * oImgH / oImgW // 等比例计算后的图片实际展示高度
let res = list.filter((item, index) => item.id == imgId)
if (leftHeight <= rightHeight) {
listLeft.push(res[0])
vm.setData({
listLeft: listLeft // 两列中的左列
})
vm.otherData.leftHeight += realHeight + itemOthersHeight // push之后将项的高度加给对应list的高度
} else {
listRight.push(res[0])
vm.setData({
listRight: listRight // 两列中的右列
})
vm.otherData.rightHeight += realHeight + itemOthersHeight
}
},
onReachBottom() {
// ...
this.setData({
hiddenImgs: res.list,
list: res.list
})
}