ホームページ  >  記事  >  WeChat アプレット  >  小さなプログラムでリストのスクロールによる上下の連動効果を実現する方法についての簡単な説明

小さなプログラムでリストのスクロールによる上下の連動効果を実現する方法についての簡単な説明

青灯夜游
青灯夜游転載
2021-12-16 10:30:243387ブラウズ

ミニ プログラムはどのようにしてリストを上下にスクロールする効果を実現できるのでしょうか?次の記事では、リストを上下にスクロールする WeChat アプレットの開発方法を紹介しますので、ご参考になれば幸いです。

小さなプログラムでリストのスクロールによる上下の連動効果を実現する方法についての簡単な説明

#1. 背景

私は現在、会社用の小さなプログラムに取り組んでいます。デザインの 1 つは上下にスクロールするものです。このとき、上部のタブバーがリンクされ、タブバーをクリックするとリストデータもリンクされます。

以下は実装のレンダリングです。

小さなプログラムでリストのスクロールによる上下の連動効果を実現する方法についての簡単な説明

#上部のヘッダー領域はリストと一緒にスクロールしません。 ヘッド領域より下の領域はスクロール領域に属します。

2. 実装

2.1 原則の導入

この場所の実装は主に、WeChat アプレットにネイティブな scroll-view コンポーネントに依存しています。

scroll-into-view 属性を使用すると、上部のタブ バーをクリックして、指定されたリスト位置までページをスクロールできます。

bindscroll イベントを使用して、スクロール距離を確認します。現在のページ、スクロール距離に基づいてタブ バーの切り替え操作を実行します;

2.1 ページ レイアウト コード

まず、インターフェイスの全体的なレイアウトについて説明します。これは主に 2 つの部分に分かれています。固定ヘッドエリアはリストエリアをスクロールすることができます。

スクロール可能なリスト領域のタイトル バーを一定距離スクロールすると、タイトル バーも上部に固定される必要があります。

コードの実装:

<!--index.wxml-->
<view class="list">

<!--顶部固定区域-->
<view style="height: 88rpx;width: 100%;background-color: burlywood;text-align: center;">头部区域</view>

<!--可滚动区域-->
<scroll-view scroll-y="true" style="width: 100%; height: {{scrollAreaHeight}}px;" bindscroll="scroll" scroll-into-view="{{scrollToItem}}" scroll-with-animation="true"  scroll-top="{{scrollTop}}">

   <!--水平滚动的tab栏-->
  <scroll-view scroll-x="true" style="height: 88rpx;width: 100%;">
  <view class="head-area {{float ? &#39;head-float&#39; : &#39;&#39;}}" >
    <view class="head-area-item {{curSelectTab === index ? &#39;head-area-item-select&#39; : &#39;&#39;}}" wx:for="{{appGroupList}}" bindtap="tabClick" data-index="{{index}}">
    {{item.name}}
  </view>
  </view>

  </scroll-view>

<!--数据列表-->
<view class="list-group" style="height: {{listGroupHeight}}px;">
  <view class="list-group-item" id="v_{{index}}" wx:for="{{appGroupList}}" data-index="{{index}}">
    <view class="group-name">
      {{item.name}}
    </view>
    <view class="group-children" >
      <view wx:for="{{item.children}}" class="group-children-item" style="width: {{itemWidth}}px;">
      <image src="{{item.url}}"></image>
      <view>{{item.name}}</view>
    </view>
    </view>

  </view>
</view> 
</scroll-view>

</view>

レイアウト コードには注意すべき点がいくつかあります:

1.scrollAreaHeight スクロール領域の高さの計算。 --- 現在のデバイスのウィンドウの高さから上部の固定領域の高さを引いた値を取得することで、水平タブ バーが上部にあるかどうかを示します。 --- ページのスクロール距離に基づいて判断し、スクロール距離が水平タブバーの高さ以上の場合、上部に移動します;

3. ID を設定します="v_{{index}}" データ リストの ID。その後のタブ バーをクリックして指定された位置までスクロールする操作は、この ID に基づいて実装されます。

2.2 スタイル コード

/**index.wxss**/
.list{
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.head-area{
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  height: 88rpx;
  width: 100%;
  padding: 0 10;
}

.head-area-item{
  display: flex;
  height: 88rpx;
  text-align: center;
  width: 150rpx;
  align-items: center;
  justify-content: center;
}

.head-area-item-select{
  color: #09bb07;
}

image{
  width: 88rpx;
  height: 88rpx;
}

.list-group{
  display: flex;
  width: 100%;
  height: 1000%;
  flex-direction: column;
}

.list-group-item{
  display: flex;
  width: 100%;
  background-color: #aaa;
  flex-direction: column;
}

.group-name{
  height: 88rpx;
  display: flex;
  text-align: center;
  align-items: center;
  margin-left: 20rpx;
}

.group-children{
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  width: 100%;
}

.group-children-item{
  height: 160rpx;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.head-float{
  position: fixed;
  top: 88rpx;
  background-color: #ffffff;
}

2.3 ロジック コード

// index.js
Page({
  heightArr: [],
  //记录scroll-view滚动过程中距离顶部的高度
  distance: 0,
  data: {
    appGroupList:[
      {name:"分组01",children:[{"name":"测试0","url":"/images/bluetooth.png"},
      {"name":"测试1","url":"/images/bluetooth.png"},
      {"name":"测试2","url":"/images/bluetooth.png"},
      {"name":"测试3","url":"/images/bluetooth.png"},
      {"name":"测试4","url":"/images/bluetooth.png"},
      {"name":"测试5","url":"/images/bluetooth.png"},
      {"name":"测试6","url":"/images/bluetooth.png"},
      {"name":"测试7","url":"/images/bluetooth.png"}]},
      {name:"分组02",children:[{"name":"测试0","url":"/images/bluetooth.png"},
      {"name":"测试1","url":"/images/bluetooth.png"},
      {"name":"测试2","url":"/images/bluetooth.png"},
      {"name":"测试3","url":"/images/bluetooth.png"},
      {"name":"测试4","url":"/images/bluetooth.png"},
      {"name":"测试5","url":"/images/bluetooth.png"},
      {"name":"测试6","url":"/images/bluetooth.png"},
      {"name":"测试7","url":"/images/bluetooth.png"}]},
      {name:"分组03",children:[{"name":"测试0","url":"/images/bluetooth.png"},
      {"name":"测试1","url":"/images/bluetooth.png"},
      {"name":"测试2","url":"/images/bluetooth.png"},
      {"name":"测试3","url":"/images/bluetooth.png"},
      {"name":"测试4","url":"/images/bluetooth.png"},
      {"name":"测试5","url":"/images/bluetooth.png"},
      {"name":"测试6","url":"/images/bluetooth.png"},
      {"name":"测试7","url":"/images/bluetooth.png"}]},
      {name:"分组04",children:[{"name":"测试0","url":"/images/bluetooth.png"},
      {"name":"测试1","url":"/images/bluetooth.png"},
      {"name":"测试2","url":"/images/bluetooth.png"},
      {"name":"测试3","url":"/images/bluetooth.png"},
      {"name":"测试4","url":"/images/bluetooth.png"},
      {"name":"测试5","url":"/images/bluetooth.png"},
      {"name":"测试6","url":"/images/bluetooth.png"},
      {"name":"测试7","url":"/images/bluetooth.png"}]},
      {name:"分组05",children:[{"name":"测试0","url":"/images/bluetooth.png"},
      {"name":"测试1","url":"/images/bluetooth.png"},
      {"name":"测试2","url":"/images/bluetooth.png"},
      {"name":"测试3","url":"/images/bluetooth.png"},
      {"name":"测试4","url":"/images/bluetooth.png"},
      {"name":"测试5","url":"/images/bluetooth.png"},
      {"name":"测试6","url":"/images/bluetooth.png"},
      {"name":"测试7","url":"/images/bluetooth.png"}]},
    ],
    itemWidth: wx.getSystemInfoSync().windowWidth / 4,
    scrollAreaHeight:wx.getSystemInfoSync().windowHeight - 44,
    float:false,
    curSelectTab:0,
    scrollToItem:null,
    scrollTop: 0, //到顶部的距离
    listGroupHeight:0,
  },

  onReady: function () {
    this.cacluItemHeight();
  },

  scroll:function(e){
    console.log("scroll:",e);
    if(e.detail.scrollTop>=44){
      this.setData({
        float : true
      })
    } else if(e.detail.scrollTop<44) {
      this.setData({
        float : false
      })
    }
    let scrollTop = e.detail.scrollTop;
    let current = this.data.curSelectTab;
    if (scrollTop >= this.distance) {
      //页面向上滑动
      //列表当前可视区域最底部到顶部的距离 超过 当前列表选中项距顶部的高度(且没有下标越界),则更新tab栏
      if (current + 1 < this.heightArr.length && scrollTop >= this.heightArr[current]) {
        this.setData({
          curSelectTab: current + 1
        })
      }
    } else { 
      //页面向下滑动
      //如果列表当前可视区域最顶部到顶部的距离 小于 当前列表选中的项距顶部的高度,则切换tab栏的选中项
      if (current - 1 >= 0 && scrollTop < this.heightArr[current - 1]) {
        this.setData({
          curSelectTab: current - 1
        })
      }
    }
    //更新到顶部的距离
    this.distance = scrollTop;
  },

  tabClick(e){
    this.setData({
      curSelectTab: e.currentTarget.dataset.index,
      scrollToItem: "v_"+e.currentTarget.dataset.index
    })
  },

  //计算每一个item高度
  cacluItemHeight() {
    let that = this;
    this.heightArr = [];
    let h = 0;
    const query = wx.createSelectorQuery();
    query.selectAll(&#39;.list-group-item&#39;).boundingClientRect()
    query.exec(function(res) {
      res[0].forEach((item) => {
        h += item.height;
        that.heightArr.push(h);
      })
      console.log(that.heightArr);
      that.setData({
        listGroupHeight: that.heightArr[that.heightArr.length - 1 ]
      })
    })
  },
})

ロジック コードには主に 2 つの場所があります:

1、cacluItemHeight 計算リスト 高さ配列アイテムの最終的な計算結果を heightArr 配列に保存します。

heightArr 配列内の各項目の値は、前の項目に基づいて累積されます。

2. スクロールで現在のスクロール方向を決定し、スクロールに基づいて現在の方向を決定し、スクロール距離に基づいて現在選択されているタブを設定します。

以上で、上記の内容を踏まえると、基本的にはスクロール連動やタブ連動の効果を実現することができます。

[関連する学習の推奨事項:

小さなプログラム開発チュートリアル

]

以上が小さなプログラムでリストのスクロールによる上下の連動効果を実現する方法についての簡単な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。