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. MySql(一)表类型(存储引擎)

    MySql(一)表类型(存储引擎) 一.MYSQL存储引擎概述 二.存储引擎的特性对比 2.1 MyISAM 2.2 InnoDB 2.2.1 自动增长列 2.2.2 外键约束 2.2.3 存储方式 ...

  2. D - Wireless Network(无线网络)

    题意:给你 N 台坏了的电脑的坐标 ,和一个距离范围 d . (在距离范围内的电脑可以相互通信,每台电脑也可以连接两台不同的电脑,使他们之间能够通信) 输入任意次数操作: O   x        表 ...

  3. zjnu1716 NEKAMELEONI (线段树)

    Description "Hey! I have an awesome task with chameleons, 5 th task for Saturday's competition. ...

  4. 牛客练习赛70 B.拼凑 (序列自动机)

    题意:有一个模板串,有\(T\)个字符串,从字符串中找到某个子串,使得这个子串中的子序列包含模板串,求最短的子串的长度. 题解:找子序列,很容易想到序列自动机,根据序列自动机的原理,我们一定可以确保除 ...

  5. JavaScript——二

    样式: 实验二. querySelectorAll()里面如果填id名称就直接写,如果要确定某个属性的值,就要用到[ ]来具体选择,其中写多个以空格隔开就表达第一个声明下的第二个标签内部的某个属性 这 ...

  6. 牛客编程巅峰赛S1第5场 - 青铜&白银 C.排队 (优先队列,归并排序)

    题意:有\(m\)个窗口,\(n\)个人排队,每个人都有各自的办理时间,只有办理完成窗口才能空出来,后面的人开始办理,求有多少人比后面的人开始办理的早但完成的晚. 题解:我们可以用优先队列来模拟办理, ...

  7. 一、Python简介及下载安装

    一.关于Python Python是目前比较受欢迎的脚本语言之一,具有简洁性.易读性以及可扩展性的特点. Python与Java均可以写网页,也可以写后台功能,区别是Python执行效率低,开发效率高 ...

  8. 如何用 4 个小时搭建一个新 “Clubhouse” ,引爆声音社交新风口

    Clubhouse,基于实时音频技术的声音社交现象级火爆 最近,让硅谷两位顶级 VC 大打出手争相投资的 Clubhouse 火到了国内,甚至在社交圈里 "一码难求",此种火爆程度 ...

  9. win10 远程桌面 ubuntu

    一.获取本机ip 通过ip查询网址来查询本机外网地址 二.下载远程链接软件 下载向日葵,注册账号 三.远程链接 将连接端与被连接端分别绑定账号,输入相应ip地址,即可连接.

  10. 弹性伸缩 AS(Auto Scaling)

    根据业务需求和策略设置伸缩规则,在业务需求增长时自动为您增加 ECS 实例以保证计算能力,在业务需求下降时自动减少 ECS 实例以节约成本,弹性伸缩不仅适合业务量不断波动的应用程序,同时也适合业务量稳 ...