经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JSJS库框架 » JavaScript » 查看文章
web页面和小程序页面实现瀑布流效果
来源:cnblogs  作者:TDX  时间:2018/9/26 17:54:35  对本文有异议

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

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

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

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

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

 

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

 页面代码:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta charset=’utf-8′> <!--声明文档使用的字符编码-->
  6. <title>瀑布流_左浮动</title>
  7. <style type="text/css">
  8. *{margin:0;padding:0;}
  9. .container {
  10. width: 1200px; height: auto; margin: 50px auto;
  11. position: relative;
  12. }
  13. .box{
  14. padding: 5px; box-shadow: 0 0 10px purple; border-radius: 5px;
  15. float: left; margin: 10px;
  16. }
  17. .box img { width: 200px; height: auto; }
  18. </style>
  19. </head>
  20. <body>
  21. <div class="container">
  22. <div class="box"><img src="../img/0.jpg"/></div>
  23. <div class="box"><img src="../img/1.jpg"/></div>
  24. <div class="box"><img src="../img/2.jpg"/></div>
  25. <div class="box"><img src="../img/3.jpg"/></div>
  26. <div class="box"><img src="../img/4.jpg"/></div>
  27. <div class="box"><img src="../img/5.jpg"/></div>
  28. <div class="box"><img src="../img/6.jpg"/></div>
  29. <div class="box"><img src="../img/7.jpg"/></div>
  30. <div class="box"><img src="../img/8.jpg"/></div>
  31. <div class="box"><img src="../img/9.jpg"/></div>
  32. <div class="box"><img src="../img/10.jpg"/></div>
  33. <div class="box"><img src="../img/11.jpg"/></div>
  34. <div class="box"><img src="../img/12.jpg"/></div>
  35. <div class="box"><img src="../img/13.jpg"/></div>
  36. <div class="box"><img src="../img/14.jpg"/></div>
  37. <div class="box"><img src="../img/15.jpg"/></div>
  38. <div class="box"><img src="../img/16.jpg"/></div>
  39. </div>
  40. <script type="text/javascript">
  41.  
  42. var boxsHeight = []; //盒子高度存储数组
  43. var boxWidth = 230, boxHeight = 230;
  44. window.onload = function(){
  45. var boxs = document.getElementsByClassName('box');
  46. var cols = Math.floor(1200.0/boxWidth); //最多几列
  47.  
  48. //offsetWidth: 包括元素的内容宽度+padding+border宽度
  49. //存储第一行的每个盒子的高度到数组里面
  50. for (var i = 0; i < cols; i++){
  51. var obj = boxs[i]; //元素节点
  52.  
  53. if (i < cols){
  54. boxsHeight.push(obj.offsetHeight);
  55. }
  56. }
  57. updateBoxFrame(cols); //从第二行开始更新元素的位置
  58. window.onscroll = pageScroll; //设置页面滚动监听函数
  59. pageScroll(); //先调用一次
  60. }
  61. //获取数组中最小值的索引
  62. function getMinHeightIndex(arr){
  63. var minHeight = Math.min.apply(null, arr);
  64. for (var i = 0; i < arr.length; i++){
  65. if (arr[i] == minHeight){
  66. return i;
  67. }
  68. }
  69. }
  70. //监听页面滚动
  71. function pageScroll(){
  72. var parentEle = document.getElementsByClassName('container')[0];
  73. var subEleCount = parentEle.childElementCount; //子元素个数
  74. var lastBox = parentEle.lastElementChild; //最后一个元素
  75.  
  76. //判断是否滚动到底部
  77. var doc = document.documentElement||document.body;
  78. console.log('滚动监听', doc.scrollTop+",", lastBox.offsetTop+", " + doc.clientHeight);
  79. if (doc.scrollTop+doc.clientHeight > lastBox.offsetTop){
  80. //表示该新添加元素了
  81. addBox();
  82. //更新新添加元素的位置
  83. updateBoxFrame(subEleCount);
  84. }
  85. }
  86. //新添加子元素
  87. function addBox(){
  88. var parentEle = document.getElementsByClassName('container')[0];
  89. var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
  90. for (var i = 0; i < arr.length; i++){
  91. var index = parseInt(Math.random()*100%arr.length);
  92. var imgNum = arr[index];
  93. var div = document.createElement('div');
  94. div.setAttribute('class', 'box');
  95. div.innerHTML = '<img src="../img/' + imgNum + '.jpg"/>'
  96. parentEle.appendChild(div);
  97. arr.splice(index, 1)
  98. }
  99. }
  100. //更新新添加元素的位置
  101. function updateBoxFrame(startIndex){
  102. var boxs = document.getElementsByClassName('box');
  103. for (var i = startIndex; i < boxs.length; i++){
  104. var obj = boxs[i];
  105. //获取数组中最小高度的索引
  106. var minHeightIndex = getMinHeightIndex(boxsHeight);
  107. // console.log(boxsHeight);
  108. // console.log(minHeightIndex + ", " +boxsHeight[minHeightIndex]);
  109. var boxTop = boxsHeight[minHeightIndex] + 20;
  110. var boxLeft = minHeightIndex * boxWidth;
  111. console.log(i + ', boxTop: ' + boxTop + ", boxLeft: " + boxLeft);
  112. //设置元素的定位样式
  113. obj.style = 'position: absolute; top:' + boxTop + "px;left:" + boxLeft+"px";
  114. boxsHeight[minHeightIndex] = boxTop + obj.offsetHeight;
  115. }
  116. }
  117. </script>
  118. </body>
  119. </html>
View Code

 

  2、小程序实现瀑布流,大致流程差不多。只不过小程序的图片的宽高度的获取没有web页面那么方便。

大概实现过程:1)、获取图片数据,页面渲染;

      2)、给图片绑定加载load事件,存储每个图片的宽高度;

      3)、计算每个图片的定位,重新渲染

  

先看小程序的效果图(瀑布流+无限循环加载):

wxml页面代码:

  1. <scroll-view class='main' scroll-y='true' style="height:{{windowHeight}}px" bindscrolltolower='loadMoreImages'>
  2. <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'/>
  3. </scroll-view>
View Code

js页面代码:

  1. // pages/discover/waterfall_flow/waterfall_flow.js
  2. Page({
  3. /**
  4. * 页面的初始数据
  5. */
  6. data: {
  7. dataList: [], //数据源
  8. windowWidth: 0, //页面视图宽度
  9. windowHeight: 0, //视图高度
  10. imgMargin: 6, //图片边距: 单位px
  11. imgWidth: 0, //图片宽度: 单位px
  12. topArr: [0, 0], //存储每列的累积top
  13. },
  14. /**
  15. * 生命周期函数--监听页面加载
  16. */
  17. onLoad: function (options) {
  18. wx.showLoading({
  19. title: '加载中...',
  20. })
  21. var that = this;
  22. //获取页面宽高度
  23. wx.getSystemInfo({
  24. success: function (res) {
  25. console.log(res)
  26. var windowWidth = res.windowWidth;
  27. var imgMargin = that.data.imgMargin;
  28. //两列,每列的图片宽度
  29. var imgWidth = (windowWidth - imgMargin * 3) / 2;
  30. that.setData({
  31. windowWidth: windowWidth,
  32. windowHeight: res.windowHeight,
  33. imgWidth: imgWidth
  34. }, function () {
  35. that.loadMoreImages(); //初始化数据
  36. });
  37. },
  38. })
  39. },
  40. //加载图片
  41. loadImage: function (e) {
  42. var index = e.currentTarget.dataset.index; //图片所在索引
  43. var imgW = e.detail.width, imgH = e.detail.height; //图片实际宽度和高度
  44. var imgWidth = this.data.imgWidth; //图片宽度
  45. var imgScaleH = imgWidth / imgW * imgH; //计算图片应该显示的高度
  46.  
  47. var dataList = this.data.dataList;
  48. var margin = this.data.imgMargin; //图片间距
  49. //第一列的累积top,和第二列的累积top
  50. var firtColH = this.data.topArr[0], secondColH = this.data.topArr[1];
  51. var obj = dataList[index];
  52. obj.height = imgScaleH;
  53. if (firtColH < secondColH) { //表示新图片应该放到第一列
  54. obj.left = margin;
  55. obj.top = firtColH + margin;
  56. firtColH += margin + obj.height;
  57. }
  58. else { //放到第二列
  59. obj.left = margin * 2 + imgWidth;
  60. obj.top = secondColH + margin;
  61. secondColH += margin + obj.height;
  62. }
  63. this.setData({
  64. dataList: dataList,
  65. topArr: [firtColH, secondColH],
  66. });
  67. },
  68. //加载更多图片
  69. loadMoreImages: function () {
  70. var imgs = [
  71. 'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1409185525,4059560780&fm=26&gp=0.jpg',
  72. 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=4076355782,2436939971&fm=15&gp=0.jpg',
  73. 'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=777075993,2126273204&fm=11&gp=0.jpg',
  74. 'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=57777155,3251523579&fm=11&gp=0.jpg',
  75. 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3825727093,2830650732&fm=11&gp=0.jpg',
  76. 'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2379065095,654347953&fm=26&gp=0.jpg',
  77. 'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2749679283,2472217536&fm=11&gp=0.jpg',
  78. 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=677128138,409184861&fm=11&gp=0.jpg',
  79. 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1884091074,3049103326&fm=26&gp=0.jpg',
  80. 'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1600363417,3661952978&fm=11&gp=0.jpg',
  81. 'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2069544162,3090555174&fm=11&gp=0.jpg',
  82. 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3328655038,3143543956&fm=26&gp=0.jpg',
  83. 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3953624046,2332872335&fm=26&gp=0.jpg',
  84. 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=717009955,687560133&fm=26&gp=0.jpg',
  85. 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=4243037288,2388509769&fm=26&gp=0.jpg',
  86. 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2644451528,4180971732&fm=26&gp=0.jpg',
  87. 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2658655215,924706045&fm=26&gp=0.jpg',
  88. 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=400545645,1325440240&fm=26&gp=0.jpg',
  89. 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2735743532,3162562682&fm=11&gp=0.jpg',
  90. 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2357555025,1781222560&fm=26&gp=0.jpg',
  91. 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1604156508,3282489713&fm=26&gp=0.jpg',
  92. 'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=380663325,2271064034&fm=26&gp=0.jpg',
  93. 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=174537541,3462862985&fm=26&gp=0.jpg',
  94. 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1752649241,364583051&fm=26&gp=0.jpg',
  95. 'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2890516059,4166188770&fm=27&gp=0.jpg',
  96. 'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2435144503,200941795&fm=11&gp=0.jpg',
  97. 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=877833827,2847590581&fm=26&gp=0.jpg',
  98. 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=894452177,2810600152&fm=11&gp=0.jpg',
  99. 'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=4053642431,248486335&fm=27&gp=0.jpg',
  100. 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2914607659,905736210&fm=11&gp=0.jpg',
  101. 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1629456501,1514429218&fm=26&gp=0.jpg',
  102. ];
  103. var tmpArr = [];
  104. for (let i = 0; i < 22; i++) {
  105. var index = parseInt(Math.random() * 100) % imgs.length;
  106. var obj = {
  107. src: imgs[index],
  108. height: 0,
  109. top: 0,
  110. left: 0,
  111. }
  112. tmpArr.push(obj);
  113. imgs.splice(index, 1);
  114. }
  115. var dataList = this.data.dataList.concat(tmpArr)
  116. this.setData({ dataList: dataList }, function(){
  117. wx.hideLoading()
  118. });
  119. },
  120. /**预览图片 */
  121. previewImg: function (e) {
  122. var index = e.currentTarget.dataset.index;
  123. var dataList = this.data.dataList;
  124. var currentSrc = dataList[index].src;
  125. // var srcArr = dataList.map(function (item) {
  126. // return item.src;
  127. // });
  128. wx.previewImage({
  129. urls: [currentSrc],
  130. })
  131. },
  132. })
View Code

wxss页面代码:

  1. .main{ width: 100%; height: 100%; position: relative; }
  2. .main image {
  3. box-shadow: 0 0 10rpx red; border-radius: 8rpx;
  4. }
View Code

 

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

 

版权声明


作者:TDX

出处:博客园TDX的技术博客--http://www.cnblogs.com/tandaxia

您的支持是对博主最大的鼓励,感谢您的认真阅读。

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

 

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

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号