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的更多相关文章

  1. taro swiper & scroll tabs

    taro swiper & scroll tabs https://taro-docs.jd.com/taro/docs/components/viewContainer/swiper.htm ...

  2. taro scroll tabs 滚动标签 切换

    taro scroll tabs 滚动标签 切换 https://www.cnblogs.com/lml-lml/p/10954069.html https://developers.weixin.q ...

  3. TabbedPaneDemo

    package swing.tabbedpane; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import ja ...

  4. Swing-选项卡面板JTabbedPane-入门

    注:非原创,内容源自<Swing 的选项卡面板>,笔者做了少量修改. 选项卡面板是一个很常用的Swing组件,在window下,右击我的电脑,查看属性,就是一个典型的选修卡面板.当然还有最 ...

  5. 布局-EasyUI Panel 面板、EasyUI Tabs 标签页/选项卡、EasyUI Accordion 折叠面板、EasyUI Layout 布局

    EasyUI Panel 面板 通过 $.fn.panel.defaults 重写默认的 defaults. 面板(panel)当做其他内容的容器使用.它是创建其他组件(比如:Layout 布局.Ta ...

  6. 微信小程序实现tabs选项卡

    选项卡在我们的日常开发中,使用的还是蛮多的,但是微信小程序中却没有直接提供选项卡组件,不过我们可以变通通过 scroll-view 和 swiper 组件来实现一个选项卡的功能. 需求: 实现一个选项 ...

  7. 【前端性能】高性能滚动 scroll 及页面渲染优化

    最近在研究页面渲染及web动画的性能问题,以及拜读<CSS SECRET>(CSS揭秘)这本大作. 本文主要想谈谈页面优化之滚动优化. 主要内容包括了为何需要优化滚动事件,滚动与页面渲染的 ...

  8. MUI开发APP,scroll组件,运用到区域滚动

    最近在开发APP的过程中,遇到一个问题,就是内容有一个固定的头部和底部.         头部就是我们常用的header了,底部的话,就放置一个button,用来提交页面数据或者进入下一个页面等,效果 ...

  9. 完美解决,浏览器下拉显示网址问题 | 完美解决,使用原生 scroll 写下拉刷新

    在 web 开发过程中我们经常遇到,不想让用户下拉看到我的地址,也有时候在 div 中没有惯性滚动,就此也出了 iScroll 这种关于滚动条的框架,但是就为了一个体验去使用一个框架好像又不值得,今天 ...

随机推荐

  1. (转载)微软数据挖掘算法:Microsoft Naive Bayes 算法(3)

    介绍: Microsoft Naive Bayes 算法是一种基于贝叶斯定理的分类算法,可用于探索性和预测性建模. Naïve Bayes 名称中的 Naïve 一词派生自这样一个事实:该算法使用贝叶 ...

  2. ResponseEntity和@ResponseBody以及@ResponseStatus区别

    看的迷迷糊糊的 https://www.jdon.com/springboot/responseentity.html

  3. navicat连接阿里云mysql数据库服务器遇到的1130等相关问题

    最近搭建自己的博客网站的时候使用了阿里云的云服务器ESC,搭建了一个mysql数据库,在windows下使用navicat连接mysql的时候,总是连接不上,出现了1130的问题等等错误信息. 下面将 ...

  4. linux上 用户间发送消息 通信

    联想:scp命令 1.使用write命令,向指定用户发送信息:           用户可以使用write命令给其他在线用户发送消息.格式: $ write zhangsan hello   worl ...

  5. WLAN参数释义及优化建议

    1.AP覆盖范围或天线角度 1)参数释义 AP覆盖范围或天线角度直接影响到了终端连接到WLAN的信号强度. 2)优化建议 在设备的工程安装过程中,合理选择AP的位置,合理调整AP的覆盖方向或外置天线的 ...

  6. 飞塔5.4和5.6版本IPSec互备冗余测试

    主电信.备联通:测试方法:修改诚盈的IPSec,将阶段一电信的对端地址改为错误的. 方法一: 通过静态路由的管理距离:电信设置为10:联通为15.经测试,可以实现自动切换,且电信恢复后 可以切换回电信 ...

  7. Atcoder ABC155_C中有关c++ STL map的用法

    题目:https://atcoder.jp/contests/abc155/tasks/abc155_c 这道题的题意是给我们n个string,让我们统计每个string出现的次数,并输出次数最多的一 ...

  8. Windows Server 2016 开启远程连接并延长过期时间

    按照下面文章配置,做完1.2步即可,其中协议号码填写 4954438 亲测有效! Server 2016默认远程桌面连接数是2个用户,如果多余两个用户进行远程桌面连接时,系统就会提示超过连接数,可以通 ...

  9. C# 之 dynamic

    C#中的dynamic用于避免编译时类型检查,编译器在运行时获取类型. dynamic无法使用VisualStudio的intelliSense(智能感知),即调用dynamic修饰的对象的方法或字段 ...

  10. [Python] Pandas 对数据进行查找、替换、筛选、排序、重复值和缺失值处理

    目录 1. 数据文件 2. 读数据 3. 查找数据 4. 替换数据 4.1 一对一替换 4.2 多对一替换 4.3 多对多替换 5. 插入数据 6. 删除数据 6.1 删除列 6.2 删除行 7. 处 ...