微信小程序-商品列表右=>左联动(二)

上一篇:《微信小程序-商品列表左=>右联动(一)》

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


右左联动.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 ,控制左侧滑栏的联动。


图片发自简书App

以下是代码,考虑到部分新手同学,几乎为每一行代码添加了注释。
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 数据请翻看上一篇:《微信小程序-商品列表左=>右联动(一)》

有不懂之处,请先翻阅上一篇,如还有疑问,那肯定是笔者没写明白,还请读者不吝留言!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,688评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,559评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,749评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,581评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,741评论 3 271
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,684评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,122评论 2 292
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,847评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,441评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,939评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,333评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,783评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,275评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,830评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,444评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,553评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,618评论 2 249

推荐阅读更多精彩内容