上一篇讲解了左=>右联动,那个还比较简单,本篇写剩下比较核心的部分,也是本次开发过程中遇到最难的部分,右=>左联动,先简单看一下演示

右左联动.gif

一、关键技术:
(1) 小程序 wxss 中使用 rpx,而 js 中 scrollTop 获取到的值是 px,所以存在rpx 转 px 的问题。以 iPhone6 为基准,转换公式:

// percent 为当前设备1rpx对应的px值
var percent = res.windowWidth / 750;

详情参考:WXSS尺寸单位

(2) 微信自带scroll-view UI组件,通过 bindscroll="scroll" 绑定滚动事件;通过 scroll-top="{{scrollTop}}" 动态控制 左侧滑栏的被动滚动。
二、实现思路:
通过计算整个右侧滑栏滚动上去的高度 与 右侧滑栏中每一个分类距顶部的距离做比对,获取到该滚动置顶的分类的 index 。然后用获取到的 index 乘以左侧滑栏中某一项的高度,动态赋值给左侧滑栏内的 scrollTop ,控制左侧滑栏的联动。

以下是代码,考虑到部分新手同学,几乎为每一行代码添加了注释。
wxml代码:标签中属性如有不懂,请自行查看小程序API,内有详细讲解!

<view class="container">  <!--左侧栏--> <scroll-view class='scroll_left' scroll-y="true" style="height:{{winHeight}}px;" scroll-with-animation="true" scroll-top="{{scrollTop}}"> <view class="nav_left"> <block wx:for="{{list}}" wx:for-index="idx" wx:for-item="itemName" wx:key="*this"> <!--当前项的id等于item项的id,那个就是当前状态--> <!--用data-index记录这个数据在数组的下标位置,使用data-id设置每个item的id值,供打开2级页面使用--> <view class="nav_left_items {{curNav == idx ? 'active' : ''}}" bindtap="switchRightTab" data-index="{{index}}" data-id="{{item.id}}" id="{{idx}}">{{itemName[0].title}}</view> </block> </view> </scroll-view> <!--右侧栏--> <scroll-view scroll-y="true" class="scroll_right" style="height:{{winHeight}}px;" scroll-into-view="{{scrollTopId}}" scroll-with-animation="true" bindscroll="scroll"> <view class="nav_right"> <view class='mink' wx:for="{{list}}" wx:for-index="idx" wx:for-item="itemName" wx:key="*this"> <view class='minl' id='{{idx}}'>{{itemName[0].title}}</view> <block wx:for="{{itemName}}" wx:key="*this" wx:for-index="idex"> <view class="nav_right_items" wx:if="{{idex>0}}"> <navigator url="../detail/detail" hover-class="other-navigator-hover"> <view> <image src="{{item.picture}}"></image> <view > <text>{{item.desc}}</text> </view> </view> </navigator> </view> </block> </view> <view style="width:100%;height:30rpx;background:#f0f4f7"></view> </view> </scroll-view> </view> 

js代码:

// pages/list-1/list-1.js
var list = require('../../utils/list.js') Page({ data: { // 左侧点击类样式 curNav: 'A', scrollTop: 0, // 定义一个空数组,用来存放右侧滑栏中每一个商品分类的 Height listHeight:'' }, // 生命周期函数--监听页面初次渲染完成 onReady: function () { var that = this; // 定义右侧标题的 rpx 高度 和 px 高度 var right_titleRpxHeight = 60; var right_titleHeight; // 定义右侧单个商品的 rpx 高度 和 px 高度 var right_contentRpxHeight = 180; var right_contentHeight; // 定义左侧单个tab的 rpx 高度 和 px 高度 var left_titleRpxHeight = 140; var left_titleHeight; // 获取可视区屏幕高度 wx.getSystemInfo({ success: function (res) { // percent 为当前设备1rpx对应的px值 var percent = res.windowWidth / 750; that.setData({ winHeight: res.windowHeight, right_titleHeight: Number(right_titleRpxHeight * percent), right_contentHeight: Number(right_contentRpxHeight * percent), left_titleHeight: Number(left_titleRpxHeight * percent) }) } }) // 把请求到的 list 中的数据赋值给 listChild1 var listChild1 = list.List[0]; // 定义一个 names ,用于存放 scroll-into-view 使用的 id var names = ''; // 循环 listChild1 中的每一项 for (var item in listChild1) { // 把 listChild1 中每一项的键值用“:”(便于后期处理)分隔开,存入 names 中,数据格式见图‘names中的数据’ names+= ":"+item; // 计算右侧每一个分类的 Height 。 // listChild1 下的每一个 item 中包含该分类的 title,所以 listChild1[item].length 需要减一 // 右侧每一个分类中每一行放两个商品,所以 this.data.right_contentHeight 除二 // 最后加上 right_titleHeight,此时 height 为右侧一个完整分类的高度 var height = (listChild1[item].length - 1) * this.data.right_contentHeight / 2 + this.data.right_titleHeight; // 同上面 names 的道理,把每一个 height 用“:”隔开放入 listHeight 中 this.data.listHeight += ":" + height; this.setData({ // 把 listChild1 赋值给 list ,供 wxml 中循环使用 list: listChild1, listHeight:this.data.listHeight }) } // 把 names 的数据切成数组 var names = names.substring(1).split(':'); this.setData({ names:names }) }, // 右侧滑栏的 bindscroll 事件函数(ES6写法) scroll(event){ // 把 listHeight 切割成数组 var height = this.data.listHeight.substring(1).split(':'); // 定义一个 index 供左侧边栏联动使用 var index = 1; var num = 0; for(var i = 0;i<height.length;i++){ // 累计右侧滑栏滚动上去的每一个分类的 Height num+=parseInt(height[i]); // 循环判断 num 是否大于右侧滑栏滚动上去的 Height ,然后 get 到 i 值赋给 index if (num > event.detail.scrollTop){ index = i+1; // 如果右侧滑栏滚动高度小于单个类别高度的 1/2 时,index 为 0 if (event.detail.scrollTop < height[0]/2) { index = 0; } break; } } // 定义并设置左侧边栏的滚动高度 var left_scrollTop = this.data.left_titleHeight*index this.setData({ scrollTop: left_scrollTop, // 动态给左侧滑栏传递对应该项的 id,用于高亮效果显示 curNav: this.data.names[index] }) }, //点击左侧 tab ,右侧列表相应位置联动 置顶 switchRightTab: function (e) { var id = e.target.id; this.setData({ scrollTopId: id, // 左侧点击类样式 curNav:id, }) } }) 

样式表 和 list 数据请翻看上一篇:《微信小程序,左右联动》

转载于:https://www.cnblogs.com/cb-bin/p/9059316.html

NO--14 微信小程序,左右联动二相关推荐

  1. 黯然微信小程序杂记(二):小程序最新版登录并进行缓存模块的实现 附源码

    黯然微信小程序杂记(二):小程序最新版登录进行缓存模块的实现 附源码 一.功能描述 二.mine.wxml界面图片 三.mine.wxml代码 四.mine.wxss代码 五.mine.js代码 六. ...

  2. 微信小程序把玩(二十八)image组件

    原文:微信小程序把玩(二十八)image组件 image组件也是一个程序不可缺少的,可以这样说一个app中image组件随处可以看到,一般 image有两种加载方式第一种是网络图片第二种是本地图片资源 ...

  3. 微信小程序把玩(二十七)audio组件

    微信小程序把玩(二十七)audio组件 原文:微信小程序把玩(二十七)audio组件 音频播放已经封装的很好!只需配合属性设置即可! (method和data配合使用) 主要属性: wxml < ...

  4. 微信小程序把玩(二十六)navigator组件

    微信小程序把玩(二十六)navigator组件 原文:微信小程序把玩(二十六)navigator组件 navigator跳转分为两个状态一种是关闭当前页面一种是不关闭当前页面.用redirect属性指 ...

  5. 微信小程序条码、二维码生成模块

    代码地址如下: http://www.demodashi.com/demo/13994.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.c ...

  6. 基于JavaSSM和微信小程序的智能二维码门禁管理系统

    目录 1 引言 2 2 系统需求分析 2 2.1开发环境 2 2.2关键技术 2 2.2.1 Spring 框架 2 2.2.2 Spring MVC 框架 3 2.2.3 Mybatis 3 2.2 ...

  7. 微信小程序开发笔记二(WXSS和CSS样式美化)

    微信小程序开发笔记二(WXSS和CSS样式美化) 一.CSS基本知识 1.Class选择器的定义 2.ID选择器的定义 3.ID选择器和class选择器的区别 4.CSS中设置颜色 5.CSS中的文本 ...

  8. 微信小程序实现生成二维码功能并下载到本地

    微信小程序实现生成二维码功能并下载到本地 背景 实现 备注 背景 有这样一个需求,后台返回了url地址,微信小程序将url地址转成二维码图片,展示在页面上,并且该二维码图片可下载到用户手机相册中 实现 ...

  9. uni-app 微信小程序 模仿 app二层楼功能

    uni-app 微信小程序 模仿 app二层楼功能 先占个坑,今天应该写不完, 后续在慢慢补全 更新 终于写完了 这个的计算量很大,我自己的安卓机测试的时候一卡一卡的,公司同事的iphone是没有问题 ...

  10. 微信小程序获取扫描二维码后携带的参数

    微信小程序获取扫描二维码后携带的参数 1.decodeURIComponent解析生成二维码的链接. /*** 生命周期函数--监听页面加载*/onLoad: function(options) {i ...

最新文章

  1. ARM汇编语言中的程序结构
  2. 1001种玩法 | 1001种玩法--数据存储(2)
  3. Go+Vue打印店远程打印小程序源码
  4. Docker 以 docker 方式运行 jenkins
  5. C++提高部分_C++类模板基本语法---C++语言工作笔记087
  6. java实现将汉字转为拼音并包含音调
  7. FTP文件传输神器:8uftp
  8. Unity3D 编辑器功能之MonoBehaviour属性
  9. 为什么计算机网络使用数字信号,计算机网络数字电子技术的作用
  10. android 九宫格封装,Android 实现九宫格、点击图片放大全屏浏览等
  11. 智慧公厕解决方案,光明源智慧公厕解决方案全解
  12. PSD的网页模版PS切图到网页生成全攻略
  13. 第十三届蓝桥杯Java-C组2022年考题个人解析
  14. nginx: 405 not allowed问题解决方法
  15. 使用string_to_array时,报错operator does not exist: character varying = text[]
  16. traceroute命令(unix)/tracert命令(windows)
  17. linux下文件对比工具详解(diff、diff3、sdiff、vimdiff和comm)
  18. 1.2.2 网络抓包工具之:Fiddler
  19. 【参考】bike+需求影响
  20. 张驰咨询:揭晓六西格玛管理(6 Sigma)长盛不衰的秘密

热门文章

  1. 视频豪横时代,应用如何快速构建视频点播能力?
  2. Android单元测试读写文件,Android Studio单元测试:读取数据(输入)文件
  3. apk ionic 破损_cordova – ionic build android不生成任何.apk文件或错误
  4. 腾讯游戏主美:二次元卡通渲染有哪些黑科技?
  5. 【忘川风华录】交互负责人:在奇幻和萌趣中探索国风的立体体验
  6. 《伊万博士: 进化》利用三角剖分算法复刻《超越光速》地图机制
  7. LNMP单机高并发的简单优化
  8. 王者荣耀赛季末上分很枯燥,可以找一个猎游陪练一起上分
  9. 重建控制文件的案例(RESETLOGS模式和NORESETLOGS模式)
  10. C++main函数的参数介绍以及如何在main函数前执行一段代码