小程序实现瀑布流效果,和web页面差不多,都要经过以下步骤:

1)、加载图片,获取图片的宽高度;

2)、根据页面需要显示几列计算每列的宽度;

3)、根据图片真实宽度和每列的宽度比,计算出图片需要显示的高度;

4)、重新对图片进行定位

  1、web页面瀑布流效果,先看效果图(瀑布流+无限滚动加载):

 页面代码:

<!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页面代码:

<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页面代码:

// 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 = [
'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1409185525,4059560780&fm=26&gp=0.jpg',
'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=4076355782,2436939971&fm=15&gp=0.jpg',
'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=777075993,2126273204&fm=11&gp=0.jpg',
'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=57777155,3251523579&fm=11&gp=0.jpg',
'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3825727093,2830650732&fm=11&gp=0.jpg',
'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2379065095,654347953&fm=26&gp=0.jpg',
'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2749679283,2472217536&fm=11&gp=0.jpg',
'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=677128138,409184861&fm=11&gp=0.jpg',
'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1884091074,3049103326&fm=26&gp=0.jpg',
'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1600363417,3661952978&fm=11&gp=0.jpg',
'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2069544162,3090555174&fm=11&gp=0.jpg',
'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3328655038,3143543956&fm=26&gp=0.jpg',
'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3953624046,2332872335&fm=26&gp=0.jpg',
'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=717009955,687560133&fm=26&gp=0.jpg',
'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=4243037288,2388509769&fm=26&gp=0.jpg',
'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2644451528,4180971732&fm=26&gp=0.jpg',
'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2658655215,924706045&fm=26&gp=0.jpg',
'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=400545645,1325440240&fm=26&gp=0.jpg',
'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2735743532,3162562682&fm=11&gp=0.jpg',
'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2357555025,1781222560&fm=26&gp=0.jpg',
'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1604156508,3282489713&fm=26&gp=0.jpg',
'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=380663325,2271064034&fm=26&gp=0.jpg',
'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=174537541,3462862985&fm=26&gp=0.jpg',
'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1752649241,364583051&fm=26&gp=0.jpg',
'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2890516059,4166188770&fm=27&gp=0.jpg',
'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2435144503,200941795&fm=11&gp=0.jpg',
'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=877833827,2847590581&fm=26&gp=0.jpg',
'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=894452177,2810600152&fm=11&gp=0.jpg',
'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=4053642431,248486335&fm=27&gp=0.jpg',
'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2914607659,905736210&fm=11&gp=0.jpg',
'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1629456501,1514429218&fm=26&gp=0.jpg',
]; 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页面代码:

.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

web瀑布流页面地址:https://github.com/xiaotanit/Tan_HtmlDemo/blob/master/JS/%E7%80%91%E5%B8%83%E6%B5%81_%E5%B7%A6%E6%B5%AE%E5%8A%A8.html

小程序瀑布流页面地址:https://github.com/xiaotanit/Tan_HtmlDemo/tree/master/wxMini/pages/discover/waterfall_flow

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=130g6z2h5r49d

web页面和小程序页面实现瀑布流效果的更多相关文章

  1. 微信小程序-创建小程序页面

    QQ讨论群:785071190 创建页面 创建小程序页面非常简单,鼠标在需要创建页面的目录右击,可看到下图菜单,选择"Page"即可创建出一个页面. 输入页面名称,回车就可以创建出 ...

  2. 20171018 在小程序页面去获取用户的OpenID

    1. 在小程序的.js 文件中增加代码 //加载页面时到后台服务去获取openID onLoad: function (options) { //OpenId wx.login({ //获取code ...

  3. 微信小程序页面跳转后js定时器没有销毁的问题

    现在有一个小程序,对页面数据的实时性很强,本来想用socket,仔细研究了一下,万剑不离其中,它是websocket.服务端不会用,所以使用了传统的http请求方式.开发微信小程序必须要知道的事 1. ...

  4. 微信小程序页面-页面跳转失败WAService.js:3 navigateTo:fail url not in app.json

    微信小程序新建页面的要素一是新建的文件名称和其子文件的名称最好一致,不然容易出问题,在小程序页面跳转中如果出现WAService.js:3 navigateTo:fail url not in app ...

  5. 微信小程序——页面跳转及传参

    小程序页面跳转 微信小程序的页面跳转依然是以传统的请求转发和请求重定向为主,tabbar的存在,有TAB页面的跳转. 为了微信小程序的简介方便,规定页面路径只能是十层,应尽量避免过多的交互方式. 1. ...

  6. [转] 微信小程序页面间通信的5种方式

    微信小程序页面间通的5种方式 PageModel(页面模型)对小程序而言是很重要的一个概念,从app.json中也可以看到,小程序就是由一个个页面组成的. 如上图,这是一个常见结构的小程序:首页是一个 ...

  7. 小程序页面跳转传参-this和that的区别-登录流程-下拉菜单-实现画布自适应各种手机尺寸

    小程序页面跳转传参 根目录下的 app.json 文件 页面文件的路径.窗口表现.设置网络超时时间.设置多 tab { "pages": [ "pages/index/i ...

  8. 微信小程序页面跳转方法总结

    微信小程序页面跳转目前有以下方法(不全面的欢迎补充): 1. 利用小程序提供的 API 跳转: // 保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack可以返回到原页面.// 注 ...

  9. 微信小程序——页面之间传递值

    小程序页面传值的方式: 1.正向传值:上一页面 -->  下一页面 url传值 本地储存 全局的app对象 2.反向传值:下一页面 -->  上一页面 本地储存 全局的app对象 先说一下 ...

随机推荐

  1. JavaScript DOM 高级程序设计读书笔记一

    创建可重用的对象 简而言之,对象就是包含一组变量(称为属性)和函数(称为方法)的集合的实例.对象通常由类派生而来,而类中定义了对象拥有的属性和方法.如果你的脚本中都是对象之间的交互操作,那么就可以称之 ...

  2. HBase LSM树存储引擎详解

    1.前提 讲LSM树之前,需要提下三种基本的存储引擎,这样才能清楚LSM树的由来: 哈希存储引擎. B树存储引擎. LSM树(Log-Structured Merge Tree)存储引擎. 2. 哈希 ...

  3. Python——built-in module Help: math

    Help on built-in module math: NAME math DESCRIPTION This module is always available. It provides acc ...

  4. PHP和JS在循环、条件判断中的不同之处

    一.条件判断: php中算  false 的情况 1. boolean:false 2. 整形:0 3.浮点型:0 4.字符串:"" "0"(其他都对) 5.空 ...

  5. 【vue】函数式组件

    在 2.5.0 及以上版本中,如果你使用了单文件组件,那么基于模板的函数式组件可以这样声明: <template functional> <div class="cell& ...

  6. 415 DOM 查找列表框、下拉菜单控件、对表格元素/表单控件进行增删改操作、创建元素并且复制节点与删除、 对表格操作、通用性和标准的事件监听方法(点击后弹窗效果以及去掉效果)

    DOM访问列表框.下拉菜单的常用属性: form.length.options.selectedindex.type       使用options[index]返回具体选项所对应的常用属性:defa ...

  7. python算法&二分查找法

    import random def random_list(n): result = [] ids = list(range(1001,1001+n)) a1 = ["赵",&qu ...

  8. 用mongo和redis查询排行榜、统计活跃用户

    nosql数据库能解决关系型数据库遇到的性能和扩展性的问题,本博客将以mongodb和redis两种nosql数据库为基础,简单的介绍下面两个业务场景的解决方案: 1.查询排行榜(以当日总步数排名为例 ...

  9. 使用python爬虫,批量爬取抖音app视频(requests+Fiddler+appium)

    抖音很火,楼主使用python随机爬取抖音视频,并且无水印下载,人家都说天下没有爬不到的数据,so,楼主决定试试水,纯属技术爱好,分享给大家.. 1.楼主首先使用Fiddler4来抓取手机抖音app这 ...

  10. 【python】【logging】python日志模块logging常用功能

    logging模块:应用程序的灵活事件日志系统,可以打印并自定义日志内容 logging.getLogger 创建一个log对象 >>> log1=logging.getLogger ...