• 微信小程序右到左联动


    上一篇说了小程序的左到右的联动效果的实现,这个还不算太难,真正为难人的是右边滑动左边的选项对应切换的效果,咱今天就讲一下。话不多说先看效果。


     
    右左联动.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="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 数据请翻看上一篇:微信小程序左到右联动

  • 相关阅读:
    orapwd创建密码文件
    ORA-00119: invalid specification for system parameter LOCAL_LISTENER
    创建和使用虚拟专用目录
    创建和使用RMAN存储脚本
    oracle归档日志管理
    Flash Recovery Area 的备份
    Flash Recovery Area空间不足导致DB不能打开或hang住处理方法
    Flash Recovery Area
    计算机组成原理实验之微程序控制器实验
    面向对象程序设计(OOP设计模式)-行为型模式之观察者模式的应用与实现
  • 原文地址:https://www.cnblogs.com/changk/p/9270799.html
Copyright © 2020-2023  润新知