scroll tabs
scroll tabs
https://github.com/NervJS/taro-ui/blob/dev/src/components/tabs/index.tsx
https://github.com/NervJS/taro-ui/blob/dev/src/components/tabs/index.tsx#L78
public constructor(props: AtTabsProps) {
super(props)
this.state = {
_scrollLeft: 0,
_scrollTop: 0,
_scrollIntoView: ''
}
this._tabId = isTest() ? 'tabs-AOTU2018' : uuid()
// 触摸时的原点
this._touchDot = 0
// 定时器
this._timer = null
// 滑动时间间隔
this._interval = 0
// 是否已经在滑动
this._isMoving = false
}
private updateState = (idx: number): void => {
if (this.props.scroll) {
// 标签栏滚动
switch (ENV) {
case Taro.ENV_TYPE.WEAPP:
case Taro.ENV_TYPE.ALIPAY:
case Taro.ENV_TYPE.SWAN: {
const index = Math.max(idx - 1, 0)
this.setState({
_scrollIntoView: `tab${index}`
})
break
}
case Taro.ENV_TYPE.WEB: {
const index = Math.max(idx - 1, 0)
const prevTabItem = this.tabHeaderRef.childNodes[index]
prevTabItem &&
this.setState({
_scrollTop: prevTabItem.offsetTop,
_scrollLeft: prevTabItem.offsetLeft
})
break
}
default: {
console.warn('AtTab 组件在该环境还未适配')
break
}
}
}
}
private handleClick(index: number, event: CommonEvent): void {
this.props.onClick(index, event)
}
private handleTouchStart(e: ITouchEvent): void {
const { swipeable, tabDirection } = this.props
if (!swipeable || tabDirection === 'vertical') return
// 获取触摸时的原点
this._touchDot = e.touches[0].pageX
// 使用js计时器记录时间
this._timer = setInterval(() => {
this._interval++
}, 100)
}
private handleTouchMove(e: ITouchEvent): void {
const { swipeable, tabDirection, current, tabList } = this.props
if (!swipeable || tabDirection === 'vertical') return
const touchMove = e.touches[0].pageX
const moveDistance = touchMove - this._touchDot
const maxIndex = tabList.length
if (
!this._isMoving &&
this._interval < MAX_INTERVAL &&
this._touchDot > 20
) {
// 向左滑动
if (current + 1 < maxIndex && moveDistance <= -MIN_DISTANCE) {
this._isMoving = true
this.handleClick(current + 1, e)
// 向右滑动
} else if (current - 1 >= 0 && moveDistance >= MIN_DISTANCE) {
this._isMoving = true
this.handleClick(current - 1, e)
}
}
}
private handleTouchEnd(): void {
const { swipeable, tabDirection } = this.props
if (!swipeable || tabDirection === 'vertical') return
clearInterval(this._timer as NodeJS.Timeout)
this._interval = 0
this._isMoving = false
}
public render(): JSX.Element {
const {
customStyle,
className,
height,
tabDirection,
animated,
tabList,
scroll,
current
} = this.props
const { _scrollLeft, _scrollTop, _scrollIntoView } = this.state
const heightStyle = { height }
const underlineStyle = {
height: tabDirection === 'vertical' ? `${tabList.length * 100}%` : '1PX',
width: tabDirection === 'horizontal' ? `${tabList.length * 100}%` : '1PX'
}
const bodyStyle: React.CSSProperties = {}
let transformStyle = `translate3d(0px, -${current * 100}%, 0px)`
if (tabDirection === 'horizontal') {
transformStyle = `translate3d(-${current * 100}%, 0px, 0px)`
}
Object.assign(bodyStyle, {
transform: transformStyle,
'-webkit-transform': transformStyle
})
if (!animated) {
bodyStyle.transition = 'unset'
}
const tabItems = tabList.map((item, idx) => {
const itemCls = classNames({
'at-tabs__item': true,
'at-tabs__item--active': current === idx
})
return (
<View
className={itemCls}
id={`tab${idx}`}
key={item.title}
onClick={this.handleClick.bind(this, idx)}
>
{item.title}
<View className='at-tabs__item-underline'></View>
</View>
)
})
const rootCls = classNames(
{
'at-tabs': true,
'at-tabs--scroll': scroll,
[`at-tabs--${tabDirection}`]: true,
[`at-tabs--${ENV}`]: true
},
className
)
const scrollX = tabDirection === 'horizontal'
const scrollY = tabDirection === 'vertical'
return (
<View
className={rootCls}
style={this.mergeStyle(heightStyle, customStyle!)}
>
{scroll ? (
<ScrollView
id={this._tabId}
className='at-tabs__header'
style={heightStyle}
scrollX={scrollX}
scrollY={scrollY}
scrollWithAnimation
scrollLeft={_scrollLeft}
scrollTop={_scrollTop}
scrollIntoView={_scrollIntoView}
>
{tabItems}
</ScrollView>
) : (
<View id={this._tabId} className='at-tabs__header'>
{tabItems}
</View>
)}
<View
className='at-tabs__body'
onTouchStart={this.handleTouchStart.bind(this)}
onTouchEnd={this.handleTouchEnd.bind(this)}
onTouchMove={this.handleTouchMove.bind(this)}
style={this.mergeStyle(bodyStyle, heightStyle)}
>
<View className='at-tabs__underline' style={underlineStyle}></View>
{this.props.children}
</View>
</View>
)
}
demo
scroll tabs的更多相关文章
- taro swiper & scroll tabs
taro swiper & scroll tabs https://taro-docs.jd.com/taro/docs/components/viewContainer/swiper.htm ...
- taro scroll tabs 滚动标签 切换
taro scroll tabs 滚动标签 切换 https://www.cnblogs.com/lml-lml/p/10954069.html https://developers.weixin.q ...
- TabbedPaneDemo
package swing.tabbedpane; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import ja ...
- Swing-选项卡面板JTabbedPane-入门
注:非原创,内容源自<Swing 的选项卡面板>,笔者做了少量修改. 选项卡面板是一个很常用的Swing组件,在window下,右击我的电脑,查看属性,就是一个典型的选修卡面板.当然还有最 ...
- 布局-EasyUI Panel 面板、EasyUI Tabs 标签页/选项卡、EasyUI Accordion 折叠面板、EasyUI Layout 布局
EasyUI Panel 面板 通过 $.fn.panel.defaults 重写默认的 defaults. 面板(panel)当做其他内容的容器使用.它是创建其他组件(比如:Layout 布局.Ta ...
- 微信小程序实现tabs选项卡
选项卡在我们的日常开发中,使用的还是蛮多的,但是微信小程序中却没有直接提供选项卡组件,不过我们可以变通通过 scroll-view 和 swiper 组件来实现一个选项卡的功能. 需求: 实现一个选项 ...
- 【前端性能】高性能滚动 scroll 及页面渲染优化
最近在研究页面渲染及web动画的性能问题,以及拜读<CSS SECRET>(CSS揭秘)这本大作. 本文主要想谈谈页面优化之滚动优化. 主要内容包括了为何需要优化滚动事件,滚动与页面渲染的 ...
- MUI开发APP,scroll组件,运用到区域滚动
最近在开发APP的过程中,遇到一个问题,就是内容有一个固定的头部和底部. 头部就是我们常用的header了,底部的话,就放置一个button,用来提交页面数据或者进入下一个页面等,效果 ...
- 完美解决,浏览器下拉显示网址问题 | 完美解决,使用原生 scroll 写下拉刷新
在 web 开发过程中我们经常遇到,不想让用户下拉看到我的地址,也有时候在 div 中没有惯性滚动,就此也出了 iScroll 这种关于滚动条的框架,但是就为了一个体验去使用一个框架好像又不值得,今天 ...
随机推荐
- DPDK CAS(compare and set)操作
前言 rte_ring是一个无锁队列,无锁队列的出队入队操作是rte_ring实现的关键.因此,本文主要讲解dpdk是怎样使用无锁机制实现rte_ring的多生产者入队操作. rte_atomic32 ...
- 结合python版本安装python-devel gcc和g++的区别 安装前做yum搜索
[test@ecs autocloudservices]# yum install python-develLoaded plugins: fastestmirrorLoading mirror sp ...
- WPF显示命名空间不存在对应名称
3个办法 1 切换到Release模式,再生成.生成成功后切换回Debug模式就不报错了.这是Release模式下找不到我们自定义的控件导致的报错.所以切换为Release后生成则可以解决此问题. 2 ...
- SpringMVC 通过commons-fileupload实现文件上传
目录 配置 web.xml SpringMVC配置文件 applicationContext.xml 文件上传 Controller 上传实现一 上传实现二 测试 依赖 配置 web.xml < ...
- 基于粒子群算法的分组背包MATLAB实现
抽空看了一段时间的粒子群算法,这里仅针对其应用于动态规划中的背包问题的情况做下总结归纳,其他应用可以之后想到了再添加. 一:分组背包问题简介 假设有3个组,每组有2个物品,每种物品有3种属性,价值.体 ...
- 硬核!八张图搞懂 Flink 端到端精准一次处理语义 Exactly-once(深入原理,建议收藏)
Flink 在 Flink 中需要端到端精准一次处理的位置有三个: Source 端:数据从上一阶段进入到 Flink 时,需要保证消息精准一次消费. Flink 内部端:这个我们已经了解,利用 Ch ...
- Jumpserver-堡垒机
Jumpserver-堡垒机 1.基于Docker搭建Jumpserver堡垒机 1.1 下载镜像 1.2 运行镜像 1.2.1 官网步骤-Docker快速启动 1.3 浏览器访问 2.Jumpser ...
- 报表生成工具ireport
最近又开始学习新的玩意儿了,扒拉扒拉网上的资源,先捣鼓个思维导图.
- Gym - 102062A、B、C、D、E、F、G、H
比赛链接:https://vjudge.net/contest/409725#problem 题面点此处进入 Gym - 102062A 题意: 就是说比赛一共发a+b+c+d个牌子,现在不带上主人公 ...
- POJ2785 4 Values whose Sum is 0 (二分)
题意:给你四组长度为\(n\)序列,从每个序列中选一个数出来,使得四个数字之和等于\(0\),问由多少种组成情况(仅于元素的所在位置有关). 题解:\(n\)最大可以取4000,直接暴力肯定是不行的, ...