您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“小程序如何實現(xiàn)列表滾動上下聯(lián)動效果”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“小程序如何實現(xiàn)列表滾動上下聯(lián)動效果”這篇文章吧。
最近在做公司的一款小程序,其中有一塊的設計的是在列表做上下滾動的是時候,頂部的tab欄跟著一起聯(lián)動,當點擊tab欄的時候,列表數(shù)據(jù)也跟隨聯(lián)動。
頂部的頭部區(qū)域不跟隨列表滾動; 頭部區(qū)域以下屬于滾動區(qū)域。
這個地方的實現(xiàn)主要借助了微信小程序原生的scroll-view組件。
使用它的 scroll-into-view 屬性,可以實現(xiàn)點擊頂部的tab欄,將頁面滾動到指定的列表位置;
使用 bindscroll 事件,可以知道當前頁面滾動的距離,根據(jù)滾動的距離做tab欄的切換操作;
先說下界面的整體布局,主要分為兩部分,頭部固定區(qū)域 + 可滾動列表區(qū)域。
可滾動的列表區(qū)域的標題欄當滾動一定的距離后,它也要固定在頂部。
代碼實現(xiàn):
<!--index.wxml--> <view class="list"> <!--頂部固定區(qū)域--> <view style="height: 88rpx;width: 100%;background-color: burlywood;text-align: center;">頭部區(qū)域</view> <!--可滾動區(qū)域--> <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 ? 'head-float' : ''}}" > <view class="head-area-item {{curSelectTab === index ? 'head-area-item-select' : ''}}" wx:for="{{appGroupList}}" bindtap="tabClick" data-index="{{index}}"> {{item.name}} </view> </view> </scroll-view> <!--數(shù)據(jù)列表--> <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 滾動區(qū)域的高度計算。 --- 通過獲取當前設備的窗口高度減去頂部固定區(qū)域的高度
2、水平tab欄是否置頂。 --- 根據(jù)頁面的滾動距離來判斷,如果滾動距離 大于或者等于 水平tab欄的高度,則置頂;
3、設置數(shù)據(jù)列表的id="v_{{index}}" id,后續(xù)點擊tab欄滾動到指定的位置就是根據(jù)這個id去實現(xiàn)的。
/**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; }
// 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) { //頁面向上滑動 //列表當前可視區(qū)域最底部到頂部的距離 超過 當前列表選中項距頂部的高度(且沒有下標越界),則更新tab欄 if (current + 1 < this.heightArr.length && scrollTop >= this.heightArr[current]) { this.setData({ curSelectTab: current + 1 }) } } else { //頁面向下滑動 //如果列表當前可視區(qū)域最頂部到頂部的距離 小于 當前列表選中的項距頂部的高度,則切換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('.list-group-item').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 ] }) }) }, })
在邏輯代碼中最主要的有兩個地方:
1、cacluItemHeight 計算列表中item的高度數(shù)組,并將最終計算的結(jié)果保存在 heightArr數(shù)組中。
heightArr數(shù)組中的每一項的值是在前一項的基礎之上進行累加。
2、scroll 中判斷當前的滾動方向,根據(jù)滾動判斷當前的方向,然后根據(jù)滾動的距離設置當前選擇的tab。
以上是“小程序如何實現(xiàn)列表滾動上下聯(lián)動效果”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。