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. pycharm设置头文件模板(for mac)

    我们要达到的效果是每次新建一个.py文件都会有头文件,关于头文件的作用之前已做解释

  2. 关于ckfinder上传文件添加自定义处理方案

    上篇博客中介绍了如何使用ckfinder中自定义按钮的功能,实现自定义上传的功能,但是却无法解决用户使用拖拽文件上传方式中添加自定义事件,今天我们来用另一种更简洁的方式来实现上传文件重名时做一些自定义 ...

  3. 【十天自制软渲染器】DAY 03:画一个三角形(向量叉乘算法 & 重心坐标算法)

    如果你喜欢我写的文章,可以把我的公众号设为星标 ,这样每次有更新就可以及时推送给你啦. 前面两天画了点和线,今天我们来画一个最简单也是最强大的面--三角形. 本文主要讲解三角形绘制算法的推导和思路(只 ...

  4. Spark调优,性能优化

    Spark调优,性能优化 1.使用reduceByKey/aggregateByKey替代groupByKey 2.使用mapPartitions替代普通map 3.使用foreachPartitio ...

  5. .Net Core 3.1浏览器后端服务(一) Web API项目搭建

    一.前言 基于CefSharp开发的浏览器项目已有一段时间,考虑到后期数据维护需要Server端来管理,故开启新篇章搭建浏览器后端服务.该项目前期以梳理服务端知识为主,后期将配合CefSharp浏览器 ...

  6. UI自动化实战进阶PO设计模式

    前言 经过前面的实战我们已经编写了几个测试用例,下面我们要用PO设计模式来调整我们的代码,让页面元素和测试业务进行分离,这样看起来直观而且后期的维护也方便. python有一个第三方的PO设计的库,既 ...

  7. 【uva 11572】Unique Snowflakes(算法效率--滑动窗口,3种实现方法)

    题意:求长度为N的序列中,最长的一个无重复元素的连续子序列. 解法:[L,R]每次R++或L++延伸就可以得到答案. 实现:(1)next[],last[]--O(n): 1 #include< ...

  8. hdu 6863 Isomorphic Strings 哈希+求公因子

    题意: t组输入,每组数据输入一个整数n,代表字符串长度.下面再输入一个字符串 你需要判断这个字符串能不能分成大于1段,且这些段的最小表示法是一样的 例如:abccab,它可以分成2段,分别是abc和 ...

  9. hdu 2089不要62 (数位dp)

    Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer). 杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来 ...

  10. 动态主席树【带修改】&& 例题 Dynamic Rankings ZOJ - 2112

    参考链接:https://blog.csdn.net/WilliamSun0122/article/details/77885781 一.动态主席树介绍 动态主席树与静态主席树的不同在于:静态主席树不 ...