開篇
直接說重點(diǎn)堆巧,本篇內(nèi)容主要實(shí)現(xiàn)的功能有:導(dǎo)航欄tap切換妄荔、導(dǎo)航欄跟隨滾動(dòng)居中顯示、手勢(shì)滑動(dòng)切換谍肤。
目前網(wǎng)上能看的講解的多多少少有些問題啦租,功能不夠完整,走了很多彎路才調(diào)整成比較穩(wěn)定效果和體驗(yàn)荒揣,開發(fā)過程中也借用了一些別人的案例篷角。下面頁面實(shí)現(xiàn)代碼全部貼上,可直接copy套用系任。
?
1恳蹲、js實(shí)現(xiàn)
js這部分頁面觸摸事件,通過觸摸判斷手勢(shì)滑動(dòng)的方向赋除,重點(diǎn)在位置阱缓。
list頁面不需要上下滾動(dòng),固定一屏的大小举农,只有左右滑動(dòng)請(qǐng)使用:
this.starthDotX = e.touches[0].pageX;
this.starthDotY = e.touches[0].pageY;
list頁面需要上下滾動(dòng)荆针,類似scroll-view效果,需上下左右滾動(dòng)請(qǐng)使用:
如果list頁面需要滾動(dòng)颁糟,使用e.touches[0].pageX方法航背。list頁面會(huì)上下滾動(dòng)到某一個(gè)點(diǎn)的時(shí)候XY軸數(shù)據(jù)與實(shí)際滑動(dòng)距離不符合,導(dǎo)致判斷方法失效棱貌,上下滑動(dòng)的同時(shí)突然執(zhí)行左右滑動(dòng)的操作玖媚,滑動(dòng)的時(shí)候亂竄的情況
this.starthDotX = e.touches[0].clientX;
this.starthDotY = e.touches[0].clientY;
判斷觸摸手勢(shì)方向的邏輯:
if(Math.abs(X) > Math.abs(Y) && X > 0 && Math.abs(X) > minOffset) {
console.log("向右滑動(dòng)");
}else if(Math.abs(X) > Math.abs(Y) && X < 0 && Math.abs(X) > minOffset) {
console.log("向左滑動(dòng)");
}else if(Math.abs(X) < Math.abs(Y) && Y > 0) {
console.log("向下滑動(dòng)");
}else if(Math.abs(X) < Math.abs(Y) && Y < 0) {
console.log("向上滑動(dòng)");
}
上代碼:
var minOffset = 30;//最小偏移量,低于這個(gè)值不響應(yīng)滑動(dòng)處理
var DtaList0 = [{Name: "錦繡未央", url:"/image/timg0.jpg"},{Name: "錦民國往事", url:"/image/timg0.jpg"},{Name: "陳情令", url:"/image/timg0.jpg"}];
var DtaList1 = [{url:"/image/timg1.jpg", Name: "笑傲江湖"},{url:"/image/timg1.jpg", Name: "繡春刀"},{url:"/image/timg1.jpg", Name: "白夜追兇"},{url:"/image/timg1.jpg", Name: "三生三世"}];
var DtaList2 = [{url:"/image/timg2.jpg", Name: "法證先鋒"},{url:"/image/timg2.jpg", Name: "無心法師"},{url:"/image/timg2.jpg", Name: "我是余歡水"}];
var DtaList3 = [{url:"/image/timg3.jpg", Name: "東宮"},{url:"/image/timg3.jpg", Name: "我只喜歡你"},{url:"/image/timg3.jpg", Name: "我只喜歡你"},{url:"/image/timg3.jpg", Name: "愛情公寓"}];
var DtaList4 = [{url:"/image/timg4.jpg", Name: "劉老根3"},{url:"/image/timg4.jpg", Name: "鎮(zhèn)魂街"},{url:"/image/timg4.jpg", Name: "仙劍奇?zhèn)b3"},{url:"/image/timg4.jpg", Name: "尋情記"}];
var DtaList5 = [{url:"/image/timg5.jpg", Name: "人民的正義"},{url:"/image/timg5.jpg", Name: "亮劍"}];
var DtaList6 = [{url:"/image/timg6.jpg", Name: "楚漢傳奇"},{url:"/image/timg6.jpg",Name: "少帥"},{url:"/image/timg6.jpg",Name: "步步驚心"}];
var DtaList7 = [{url:"/image/timg7.jpg", Name: "大唐女法醫(yī)"},{url:"/image/timg7.jpg", Name: "十二傳說"}];
var DtaList8 = [{url:"/image/timg8.jpg", Name: "甄嬛傳"},{url:"/image/timg8.jpg", Name: "蕭十一郎"},{url:"/image/timg8.jpg", Name: "開國大典"}];
var DtaListArray = [DtaList0, DtaList1, DtaList2, DtaList3, DtaList4, DtaList5, DtaList6, DtaList7]
Page({
/*
* 頁面的初始數(shù)據(jù)
*/
data: {
DtaList: [{}], //存放每個(gè)頁面list數(shù)據(jù)
activeId: "", //記錄導(dǎo)航欄tap的id
tabIndex: 0,//記錄導(dǎo)航欄點(diǎn)擊位置
starthDotX : 0, //觸摸事件開始X軸的位置
starthDotY : 0,//觸摸事件開始Y軸的位置
TypeList: [{posterId: 10561005, typeDesc: "央視網(wǎng)"},{posterId: 10561003, typeDesc: "愛奇藝"},{posterId: 10561008, typeDesc: "騰訊視頻"},{posterId: 10561010, typeDesc: "PPTV"},{posterId: 10561002, typeDesc: "優(yōu)酷"},{posterId: 10561007, typeDesc: "嗶哩嗶哩"}, {posterId: 10561006, typeDesc: "芒果TV"}, {posterId: 10561004, typeDesc: "西瓜視頻"}] //導(dǎo)航欄假數(shù)據(jù)
},
/*****************************tap切換點(diǎn)擊事件*****************************/
changeTab: function (e) {
var id = e.target.dataset.type;
var index = e.target.dataset.index;
//禁止tap重復(fù)點(diǎn)擊
if(index == this.data.tabIndex){
return
}
//改變tap點(diǎn)擊位置
this.setData({
activeId: id,
tabIndex:index,
DtaList: DtaListArray[index]
});
//當(dāng)前tab點(diǎn)擊欄居中顯示
var singleNavWidth = this.data.windowWidth / 5;
this.setData({
navScrollLeft: (index - 2) * singleNavWidth
})
},
/*****************************觸摸事件*****************************/
//觸摸開始
touchstart: function(e){
// this.starthDotX = e.touches[0].pageX;
// this.starthDotY = e.touches[0].pageY;
this.starthDotX = e.touches[0].clientX;
this.starthDotY = e.touches[0].clientY;
},
//觸摸進(jìn)行中
touchmove: function(e){
var Direction = ""
// var moveDotX = e.touches[0].pageX;
// var moveDotY = e.touches[0].pageY;
var moveDotX = e.touches[0].clientX;
var moveDotY = e.touches[0].clientY;
var X = moveDotX - this.starthDotX;
var Y = moveDotY - this.starthDotY;
if(Math.abs(X) > Math.abs(Y) && X > 0 && Math.abs(X) > minOffset) {
Direction = "右滑"
}else if(Math.abs(X) > Math.abs(Y) && X < 0 && Math.abs(X) > minOffset) {
Direction = "左滑"
}else if(Math.abs(X) < Math.abs(Y) && Y > 0) {
Direction = "下滑"
}else if(Math.abs(X) < Math.abs(Y) && Y < 0) {
Direction = "上滑"
}
//記錄當(dāng)前滑動(dòng)方向
this.setData({
glideDirection: Direction
})
},
//觸摸結(jié)束
touchend: function(e){
if(this.data.glideDirection == "右滑"){
if(this.data.tabIndex !== 0){
var typeData = this.data.TypeList[this.data.tabIndex - 1];
var posterId = typeData.posterId;
//改變tap點(diǎn)擊位置
this.setData({
activeId: posterId,
tabIndex: this.data.tabIndex - 1,
DtaList: DtaListArray[this.data.tabIndex - 1]
})
//新增tab點(diǎn)擊當(dāng)前欄居中顯示
var singleNavWidth = this.data.windowWidth / 5;
this.setData({
navScrollLeft: (this.data.tabIndex - 2) * singleNavWidth
})
}else{
console.log("我是第一個(gè)滑不動(dòng)啦婚脱,不要滑啦=衲АI紫瘛!")
}
}else if(this.data.glideDirection == "左滑"){
if(this.data.tabIndex !== this.data.TypeList.length -1){
var typeData = this.data.TypeList[this.data.tabIndex + 1];
var posterId = typeData.posterId;
//改變tap點(diǎn)擊位置
this.setData({
activeId: posterId,
tabIndex: this.data.tabIndex + 1,
DtaList: DtaListArray[this.data.tabIndex + 1]
})
//tab點(diǎn)擊當(dāng)前欄居中顯示
var singleNavWidth = this.data.windowWidth / 5;
this.setData({
navScrollLeft: (this.data.tabIndex - 2) * singleNavWidth
})
}else{
console.log("已經(jīng)是最后一個(gè)啦错森,不要滑啦R骰隆!涩维!")
}
}
},
//列表cell點(diǎn)擊事件
clickBrand: function (e) {
var index = e.currentTarget.id;
var listData = this.data.DtaList[index];
console.log("當(dāng)前點(diǎn)擊的是:" + listData.Name)
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面加載
*/
onLoad: function (options) {
//改變tap點(diǎn)擊位置
this.setData({
activeId: '10561005',
DtaList: DtaList0
});
//新增獲取屏幕Width
wx.getSystemInfo({
success: (res) => {
this.setData({
windowWidth: res.windowWidth
})
},
})
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面顯示
*/
onShow: function () {//頁面已經(jīng)顯示出來
}
})
?
2殃姓、wxml實(shí)現(xiàn)
這部分沒有太多難度,跟搭積木一樣瓦阐,一個(gè)view一個(gè)view的嵌套蜗侈。
導(dǎo)航欄部分
原理:通過<scroll-view>控件實(shí)現(xiàn),for循環(huán)每一個(gè)按鈕睡蟋,實(shí)現(xiàn)點(diǎn)擊/滑動(dòng)切換踏幻。
控件屬性:scroll-left="{{navScrollLeft}} -> 用來控制當(dāng)前點(diǎn)擊欄滾動(dòng)的位置,滾動(dòng)居中效果薄湿。
list列表部分
原理:沒有使用系統(tǒng)swiper組件叫倍,而是通過for循環(huán)<view>的形式實(shí)現(xiàn)。
控件屬性:bindtouchstart="touchstart" / bindtouchmove="touchmove"/ bindtouchend="touchend" -> 監(jiān)聽list頁面的觸摸動(dòng)作
上代碼:
<scroll-view scroll-x="true" class="ip_tab_comtainer" scroll-with-animation="{{true}}" scroll-left="{{navScrollLeft}}">
<block wx:for="{{TypeList}}" wx:for-item="item" wx:ky = "*this" wx:for-index = "index">
<view class="ip_tab_item_n {{activeId == item.posterId?'active':''}}" bindtap="changeTab" data-type="{{item.posterId}}" data-index="{{index}}">{{item.typeDesc}}
</view>
</block>
</scroll-view>
<view class = "hotView" bindtouchstart="touchstart" bindtouchmove="touchmove" bindtouchend="touchend">
<view class = "hotCell" wx:for = "{{DtaList}}" wx:for-item='item' wx:for-index="dindex" wx:ky = "*this" bindtap = "clickBrand" id = "{{dindex}}">
<view class='imageBottomView'>
<image src="{{item.url}}"></image>
</view>
<view class='textBottom'>
<view class ="title" style="opacity:{{1}}">{{item.Name}}</view>
</view>
</view>
</view>
?
3豺瘤、wxss實(shí)現(xiàn)
這部分沒有太多可說的吆倦,樣式自己慢慢去調(diào)。
上代碼:
page{
background-color: #F1F1F1;
}
::-webkit-scrollbar{/*隱藏scrollerView滾動(dòng)條*/
width: 0;
height: 0;
color: transparent;
}
.ip_tab_comtainer {
width: 100%;
display: flex;
position:fixed;
margin-bottom: 6rpx;
white-space: nowrap;
background-color: #ffffff;
}
.ip_tab_item_n {
display: inline-block;
margin: 0rpx 25rpx 0rpx 25rpx;
padding: 28rpx 0rpx 20rpx 0rpx;
color: #666666;
font-size: 32rpx;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
}
.active{
color: #F7353B;
border-bottom: 6rpx solid #F7353B;
}
.hotView {
display: flex;
flex-wrap: wrap;
padding-top: 120rpx;
}
.hotView .hotCell {
width: 46%;
text-align: center;
margin-bottom: 20rpx;
margin-left: 15rpx;
margin-right: 15rpx;
}
.imageBottomView{
width: 100%;
height: 450rpx;
}
.imageBottomView image{
width: 100%;
height: 100%;
border-radius: 5px 5px 0px 0px;
}
.textBottom{
height: 65rpx;
display: flex;
align-items: center;
background-color: white;
border-radius: 0px 0px 5px 5px;
}
.textBottom .title{
width: 65%;
color: #5E5E5E;
text-align: left;
font-size: 30rpx;
}
如有不足歡迎留言一起補(bǔ)充探討 ~