web页面和微信小程序页面实现瀑布流效果


Posted in Javascript onSeptember 26, 2018

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

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

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

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

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

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

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)、计算每个图片的定位,重新渲染

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

web页面和微信小程序页面实现瀑布流效果

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

总结

以上所述是小编给大家介绍的web页面和微信小程序页面实现瀑布流效果 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
Javascript 遍历对象中的子对象
Jul 03 Javascript
javascript 遍历验证所有文本框的值
Aug 27 Javascript
利用js实现遮罩以及弹出可移动登录窗口
Jul 08 Javascript
JS.getTextContent(element,preformatted)使用介绍
Sep 21 Javascript
详解JavaScript正则表达式中的global属性的使用
Jun 16 Javascript
JavaScript中rem布局在react中的应用
Dec 09 Javascript
jQuery Raty 一款不错的星级评分插件
Aug 24 Javascript
基于ES6作用域和解构赋值详解
Nov 03 Javascript
vue--vuex详解
Apr 15 Javascript
Vue的编码技巧与规范使用详解
Aug 28 Javascript
原生js实现文件上传、下载、封装等实例方法
Jan 05 Javascript
Vue Router中应用中间件的方法
Aug 06 Javascript
Vue2.5学习笔记之如何在项目中使用和配置Vue
Sep 26 #Javascript
Vue监听事件实现计数点击依次增加的方法
Sep 26 #Javascript
在vue 中使用 less的教程详解
Sep 26 #Javascript
vue如何进行动画的封装
Sep 26 #Javascript
vue使用rem实现 移动端屏幕适配
Sep 26 #Javascript
ExtJs使用自定义插件动态保存表头配置(隐藏或显示)
Sep 25 #Javascript
解决IE11 vue +webpack 项目中数据更新后页面没有刷新的问题
Sep 25 #Javascript
You might like
一周让你学会PHP 不错的学习资料
2009/02/06 PHP
mac环境中使用brew安装php5.5.15
2014/08/18 PHP
typecho插件编写教程(五):核心代码
2015/05/28 PHP
Yii2使用swiftmailer发送邮件的方法
2016/05/03 PHP
Yii中的cookie的发送和读取
2016/07/27 PHP
php魔法函数与魔法常量使用介绍
2017/07/23 PHP
js时间戳格式化成日期格式的多种方法
2013/11/11 Javascript
js图片卷帘门导航菜单特效代码分享
2015/09/10 Javascript
js数组去重的5种算法实现
2015/11/04 Javascript
理解javascript中的with关键字
2016/02/15 Javascript
[原创]jQuery常用的4种加载方式分析
2016/07/25 Javascript
js仿淘宝商品放大预览功能
2017/03/15 Javascript
深入理解vue-router之keep-alive
2017/08/31 Javascript
Vue使用高德地图搭建实时公交应用功能(地图 + 附近站点+线路详情 + 输入提示+换乘详情)
2018/05/16 Javascript
vue element-ui实现动态面包屑导航
2019/12/23 Javascript
[01:05:29]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Aster BO3 第二场 1月24日
2021/03/11 DOTA
使用url_helper简化Python中Django框架的url配置教程
2015/05/30 Python
python中根据字符串调用函数的实现方法
2016/06/12 Python
python爬取淘宝商品详情页数据
2018/02/23 Python
python3+PyQt5实现文档打印功能
2018/04/24 Python
Python实现的简单排列组合算法示例
2018/07/04 Python
python+selenium 定位到元素,无法点击的解决方法
2019/01/30 Python
django框架实现一次性上传多个文件功能示例【批量上传】
2019/06/19 Python
Jupyter notebook如何实现指定浏览器打开
2020/05/13 Python
基于python获取本地时间并转换时间戳和日期格式
2020/10/27 Python
Python __slots__的使用方法
2020/11/15 Python
澳大利亚的奢侈品牌:Oroton
2016/08/26 全球购物
美国著名珠宝品牌之一:Jared The Galleria Of Jewelry
2016/10/01 全球购物
音乐教学随笔感言
2014/02/19 职场文书
应用心理学专业求职信
2014/08/04 职场文书
人民调解协议书范本
2014/10/11 职场文书
杨善洲观后感
2015/06/04 职场文书
2015秋季开学演讲稿范文
2015/07/16 职场文书
教师学习中国梦心得体会
2016/01/05 职场文书
《夸父追日》教学反思
2016/02/20 职场文书
MySQL创建索引需要了解的
2021/04/08 MySQL