
如何在微信小程序中实现今日头条App那样的Topbar
来源:
浏览:110
时间:2023-08-11
今日头条App的Topbar是一个典型的频道管理和切换组件,自己前段时间研究了一番,在微信小程序上也实现了类似的效果。
我们先看具体效果好了 ↓↓↓
GitHub
接下来,简要说一下实现思路。
WXML
{{ navbarArray[item].text }}
空白
scroll-viewnavbarArraynavbarShowIndexArraynavbarArray
navbarArraynavbarShowIndexArray
点击某个频道名称,就会触发对应频道的切换操作。
view.navbar-arrow-downfixed
显示频道
{{ navbarArray[item].text }}
上移
{{ navbarArray[item].text }}
上移
navbarShowIndexArraynavbarHideIndexArray
Modal显示的时候,Topbar需要被另一个写有“频道设置”字样的Bar覆盖。
频道设置
data
data: {
navbarArray: [{
text: '推荐',
type: 'navbar-item-active'
}, {
text: '热点',
type: ''
}, {
text: '视频',
type: ''
}, {
text: '图片',
type: ''
}, {
text: '段子',
type: ''
}, {
text: '社会',
type: ''
}, {
text: '娱乐',
type: ''
}, {
text: '科技',
type: ''
}, {
text: '体育',
type: ''
}, {
text: '汽车',
type: ''
}, {
text: '财经',
type: ''
}, {
text: '搞笑',
type: ''
}],
navbarShowIndexArray: Array.from(Array(12).keys()),
navbarHideIndexArray: [],
channelSettingShow: '',
channelSettingModalShow: '',
channelSettingModalHide: true
}
navbar-item-activeClassnavbarShowIndexArraynavbarArray
navbarShowIndexArray
storeNavbarShowIndexArray: function() {
wx.setStorage({
key: 'navbarShowIndexArray',
data: this.data.navbarShowIndexArray
});
}
切换频道的函数如下:
switchChannel: function(targetChannelIndex) {
this.getArticles(targetChannelIndex);
let navbarArray = this.data.navbarArray;
navbarArray.forEach((item, index, array) => {
item.type = '';
if (index === targetChannelIndex) {
item.type = 'navbar-item-active';
}
});
this.setData({
navbarArray: navbarArray,
currentChannelIndex: targetChannelIndex
});
}
这样,频道的管理和简单切换我们就实现了。
但是,到此为止,频道的切换只能通过点击对应Topbar中频道那一小块区域来实现,要是在正文区域左滑和右滑也能切换频道就好了。
touch
onTouchstartArticles: function(e) {
this.setData({
'startTouchs.x': e.changedTouches[0].clientX,
'startTouchs.y': e.changedTouches[0].clientY
});
},
onTouchendArticles: function(e) {
let deltaX = e.changedTouches[0].clientX - this.data.startTouchs.x;
let deltaY = e.changedTouches[0].clientY - this.data.startTouchs.y;
if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 10) {
let deltaNavbarIndex = deltaX > 0 ? -1 : 1;
let currentChannelIndex = this.data.currentChannelIndex;
let navbarShowIndexArray = this.data.navbarShowIndexArray;
let targetChannelIndexOfNavbarShowIndexArray = navbarShowIndexArray.indexOf(currentChannelIndex) + deltaNavbarIndex;
let navbarShowIndexArrayLength = navbarShowIndexArray.length;
if (targetChannelIndexOfNavbarShowIndexArray >= 0 && targetChannelIndexOfNavbarShowIndexArray <= navbarShowIndexArrayLength - 1) {
let targetChannelIndex = navbarShowIndexArray[targetChannelIndexOfNavbarShowIndexArray];
if (navbarShowIndexArrayLength > 6) {
let scrollNavbarLeft;
if (targetChannelIndexOfNavbarShowIndexArray < 5) {
scrollNavbarLeft = 0;
} else if (targetChannelIndexOfNavbarShowIndexArray === navbarShowIndexArrayLength - 1) {
scrollNavbarLeft = this.rpx2px(110 * (navbarShowIndexArrayLength - 6));
} else {
scrollNavbarLeft = this.rpx2px(110 * (targetChannelIndexOfNavbarShowIndexArray - 4));
}
this.setData({
scrollNavbarLeft: scrollNavbarLeft
});
}
this.switchChannel(targetChannelIndex);
}
}
}
GitHub


