原生js实现瀑布流及微信小程序中使用左右两列实现瀑布流

115次阅读

共计 6881 个字符,预计需要花费 18 分钟才能阅读完成。

使用 css 实现瀑布流并不实用,因为潮汕市实现的瀑布流都是以列来排列的,这里记录下用 js 实现瀑布流,以及微信小程序中使用左右两列来实现瀑布流
1. 效果图

2. 原生 js 实现瀑布流
html 文件
<div id=”root”>
<div class=”item”>
<div class=”itemImg”>
<img src=”../images/1.jpeg” alt=”” />
</div>
</div>
<div class=”item”>
<div class=”itemImg”>
<img src=”../images/3.jpeg” alt=”” />
</div>
</div>
<div class=”item”>
<div class=”itemImg”>
<img src=”../images/2.jpg” alt=”” />
</div>
</div>
</div>

图片可以自己找点替换下就可以了
css 文件

*{
margin: 0;
padding: 0;
}
#root{
position: relative;
}
.item{
float: left;
padding: 5px;
}
/* 添加阴影的时候,加上 border 会显得更加有点悬浮感 */
.itemImg{
padding: 5px;
border: 1px solid #ccc;
box-shadow: 0 0 5px #ccc;
border-radius: 5px;
}
.itemImg img{
width: 230px;
height: auto;
}
js 文件
window.onload = function () {

/* 计算图片列数及获取最小高度图片 */
generateImg(‘root’, ‘item’);

/* 对窗口大小改变进行监听,大小改变则重新布局 */
window.addEventListener(‘resize’, function() {
generateImg(‘root’, ‘item’)
});

/* 图片对象 */
let imgData = {
images: [
{
“src”:”23.png”
},
{
“src”:”22.png”
},
{
“src”:”2.jpg”
},
{
“src”:”4.jpg”
},
{
“src”:”7.jpg”
}
]
};
/* 对滚动监听 */
window.addEventListener(‘scroll’, function() {
if(checkIsScroll()) {
let rootElement = document.getElementById(‘root’);
/* 利用 documentFragment 来创建 */
// let documentFragment = document.createDocumentFragment();
let length = imgData.images.length;

/* 循环创建图片组 */
for(let i = 0; i < length; i++) {
let itemElement = document.createElement(‘div’);
itemElement.className = ‘item’;
rootElement.appendChild(itemElement);
let itemImgElement = document.createElement(‘div’);
itemImgElement.className = ‘itemImg’;
itemElement.appendChild(itemImgElement);
let itemImg = document.createElement(‘img’);
itemImg.style.cssText = ‘opacity: 0; transform:scale(0)’;
itemImg.src = “../images/” + imgData.images[i].src;
itemImgElement.appendChild(itemImg);
// documentFragment.appendChild(itemElement);

/* 在 1 秒后让图片显示出来 */
(function(img){
setTimeout(function(){
img.style.cssText=”opacity:1;transform:scale(1)”;
},1000);
})(itemImg);
}
// rootElement.appendChild(documentFragment);
generateImg(‘root’, ‘item’);
}
});
};

/* 计算图片列数及获取最小高度图片 */
function generateImg(parent, content) {
/* 获取父元素及其所以节点内容 */
let parentElement = document.getElementById(parent);
let childContent = getChildElement(parentElement, content);

/* 获取图片宽度 */
let imgWidth = childContent[0].offsetWidth;
/* 获取一行图片形成的列数 */
let imgColumn = Math.floor(document.documentElement.clientWidth / imgWidth);
/* 重新设置父级容器的宽度 */
parentElement.style.cssText = ‘width:’ + imgColumn * imgWidth + ‘px;margin:0 auto’;

/* 存储每个图片的高度,以此来找到最小图片高 */
let imgHeightArray = [];
let length = childContent.length;
for(let i = 0; i < length; i++) {
/* i<imgColumn 统计每一行的图片高度 */
if(i < imgColumn) {
/* 防止用户改变窗口大小时,内容样式错乱 */
childContent[i].style.cssText = ”;
imgHeightArray.push(childContent[i].offsetHeight);
} else {
/* 如果不是这一行的,则找到最小值和最小值的索引值 */
let minHeight = getMinImgHeight(imgHeightArray);
let minHeightIndex = getMinHeightIndex(imgHeightArray, minHeight);
/* 对这个图片设置位置 */
childContent[i].style.position = ‘absolute’;
childContent[i].style.top = minHeight + ‘px’;
childContent[i].style.left = childContent[minHeightIndex].offsetLeft + ‘px’;
/* 更换此时的最小高度 */
imgHeightArray[minHeightIndex] = childContent[i].offsetHeight + minHeight;
}
}
}

/* 检测滚动是否达到了可视区 */
function checkIsScroll() {
/* 获取 root 根节点 */
let parentElement = document.getElementById(‘root’);
/* 获取父元素下的类名为 box 的元素节点 */
let childContent = getChildElement(parentElement, ‘item’);

/* 获取最后一个元素的高度 */
let lastElementHeight = childContent[childContent.length – 1].offsetTop;
/* 获取滚动的距离 */
let scrollTopSpace = document.documentElement.scrollTop || document.body.scrollTop;
/* 获取可视区的距离 */
let clientHeight = document.documentElement.clientHeight || document.body.clientHeight;

if(lastElementHeight > scrollTopSpace + clientHeight) {
return true;
}
}
/* 获取子节点的所有内容 */
function getChildElement(parentElement, content) {
/* 存储元素信息 */
let elementArray = [];
/* 获取父元素下的所有节点信息 */
let allElement = parentElement.getElementsByTagName(‘*’);
let length = allElement.length;
for (let i = 0; i < length; i++) {
/* 找到对应的类名 */
if (allElement[i].className === content) {
elementArray.push(allElement[i]);
}
}
return elementArray;
}

/* 获取图片最小高度 */
function getMinImgHeight(heightArray) {
let length = heightArray.length;
let minHeight = heightArray[0];
for(let i = 0; i < length; i++) {
minHeight = Math.min(minHeight, heightArray[i]);
}
return minHeight;
}

/* 获取图片最小高度的索引值 */
function getMinHeightIndex(heightArray, minHeight) {
let length = heightArray.length;
for(let i = 0; i < length; i++) {
if(heightArray[i] == minHeight) {
return i;
}
}
}
3. 微信小程序中实现瀑布流
效果图

wxml 文件
<view class=”cateCommodity”>
<view class=”leftContainer”>
<block wx:for=”{{imageArray}}” wx:key=”{{item.id}}”>
<view class=”cateItem” wx:if=”{{index%2==0}}”>
<view class=”item”>
<image src=”{{item.src}}” class=”itemImg” mode=”widthFix”></image>
<view class=”title”>{{item.title}}</view>
</view>
</view>
</block>
</view>
<view class=”rightContainer”>
<block wx:for=”{{imageArray}}” wx:key=”{{item.id}}”>
<view class=”cateItem” wx:if=”{{index%2==1}}”>
<view class=”item”>
<image src=”{{item.src}}” class=”itemImg” mode=”widthFix”></image>
<view class=”title”>{{item.title}}</view>
</view>
</view>
</block>
</view>
</view>
<view class=”skipTop” catchtap=”skipTop” wx:if=”{{showTopImage}}”>
<image src=”http://boweisou.oss-cn-shenzhen.aliyuncs.com/images/0/2018/11/ZBtqujbbcGjBDgjt0bbJqbTuGqq0z8.png”></image>
</view>
wxss 文件
page{
background: #f6f6f6;
}
/* 最外层 */
.cateCommodity {
display: flex;
padding: 20rpx 28rpx 8rpx;
box-sizing: border-box;
font-size: 28rpx;
}
/* 左右两个容器 */
.leftContainer{
display: flex;
margin-right: 22rpx;
flex-direction: column;
}
.rightContainer{
display: flex;
flex-direction: column;
}
/* 图片容器 */
.cateItem {
margin-bottom: 20rpx;
}
.item{
padding: 20rpx 22rpx;
width: 335rpx;
box-sizing: border-box;
background: #fff;
border-radius: 6rpx;
}
.itemImg{
margin-bottom: 14rpx;
width: 100%;
vertical-align: middle;
border-radius: 6rpx;
}
.title{
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
line-height: 1.5;
}
/* 返回顶部 */
.skipTop {
position: fixed;
bottom: 30rpx;
right: 20rpx;
width: 90rpx;
height: 90rpx;
}

.skipTop image {
width: 100%;
height: 100%;
vertical-align: middle;
}
js 文件
Page({
data: {
imageArray: [
{
id: 1,
src: ‘../../images/avatar.jpeg’,
title: ‘ 现代新中式创意陶瓷简约摆件客厅家居玄关软装饰品家居酒柜盘子 ’
},
{
id: 1,
src: ‘../../images/avatar3.jpg’,
title: ‘ 秋冬季新款 2018 休闲运动服套装女士韩版金丝绒卫衣加绒加厚两件套 ’
},
{
id: 1,
src: ‘../../images/avatar4.jpeg’,
title: ‘ 女童床上用品四件套公主房 1.2m 床品纯棉女孩 1.8 儿童床单三件套 1.5’
},
{
id: 1,
src: ‘../../images/avatar7.jpg’,
title: ‘ 婴儿床圆床蚊帐落地款宝宝椭圆床蚊帐支架款儿童床蚊帐 BB 床小蚊帐 ’
},
{
id: 1,
src: ‘../../images/avatar9.jpeg’,
title: ‘ 包邮动感 158T 速滑鞋轮滑鞋竞速鞋高端碳纤鞋 固定码 专业定制 ’
},
{
id: 1,
src: ‘../../images/logo7.jpg’,
title: ‘Infanton 落地婴儿床蚊帐带支架儿童床蚊帐宝宝蚊帐婴童蚊帐 ’
},
{
id: 1,
src: ‘../../images/logo6.jpg’,
title: ‘ 老 A 轮滑 米高 seba hl 碳纤版 SEBA HL CARBON 平花鞋刹车鞋全能鞋 ’
},
{
id: 1,
src: ‘../../images/logo.jpeg’,
title: ‘ 洋洋法代 sandro 17 秋冬 一粒扣羊毛长款大衣外套 EKIN M9575H’
},
],
showTopImage: false,
},
onPageScroll(event) {
/* 利用两个条件,防止重复的进行 setData 操作 */
if (event.scrollTop > 300 && this.data.showTopImage == false) {
this.setData({
showTopImage: true
})
} else if (event.scrollTop < 300 && this.data.showTopImage == true) {
this.setData({
showTopImage: false
})
}
},
skipTop() {
/* 返回顶部 */
wx.pageScrollTo({
scrollTop: 0,
duration: 300
});
this.setData({
showTopImage: false
});
},
onReachBottom: function () {
let temporaryArray = this.data.imageArray;
temporaryArray.push(…this.data.imageArray);
this.setData({
imageArray: temporaryArray
})
},
})
左右两列实现瀑布流其实就是对同一数组进行了两次渲染,只是把其中的一半给隐藏了
正在努力学习中,若对你的学习有帮助,留下你的印记呗(点个赞咯 ^_^)

往期好文推荐:

判断 iOS 和 Android 及 PC 端
纯 css 实现瀑布流(multi-column 多列及 flex 布局)
实现单行及多行文字超出后加省略号
微信小程序之购物车和父子组件传值及 calc 的注意事项

正文完
 0