第一种tsx部分
import { Component } from 'react'
import './index.scss'
export default class index extends Component {
state = { start: 0, move: 0, index: 0, arr: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }
render() {
const { start, move, index, arr } = this.state
return (
<div className='app'>
<div className='ul'>
<div
className='ulSub'
style={{ left: index > 0 && index < 7 ? -75 * index + 75 : index === 0 ? 0 : -375 }}
>
<div className='slide' style={{ left: 75 * index + 18 }}></div>
{arr.map((e, i) => (
<div
className={index === i ? 'active' : ''}
onTouchStart={(e) => this.setState({ index: i })}
>
{e}
</div>
))}
</div>
</div>
<div
className='sub'
style={{ left: index * -375 }}
onTouchStart={(e) => this.setState({ start: e.changedTouches[0].pageX, move: 0 })}
onTouchMove={(e) => this.setState({ move: e.changedTouches[0].pageX - start })}
onTouchEnd={(e) => {
if (move > 50) index > 0 && this.setState({ index: index - 1 })
else if (move < -50) index < 9 && this.setState({ index: index + 1 })
}}
>
{arr.map((e) => (
<div>{e}</div>
))}
</div>
</div>
)
}
}
第二种scss部分
.app {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
.sub {
position: relative;
width: 1000%;
height: 90vh;
display: flex;
transition: .6s;
div {
width: 100vw;
height: 100%;
text-align: center;
line-height: 100vh;
font-size: 100px;
}
}
.ul {
position: relative;
width: 100vw;
height: 10vh;
top: 0;
background-color: red;
.ulSub {
transition: .6s;
position: absolute;
width: 200vw;
height: 100%;
background-color: pink;
display: flex;
div {
width: 20vw;
height: 100%;
text-align: center;
line-height: 10vh;
border: 1px solid #000;
}
.slide {
position: absolute;
width: 10vw;
height: 10px;
border-radius: 5px;
background-color: red;
top: 9vh;
z-index: 20;
transition: .1s;
}
.active {
font-weight: 700;
font-size: 30px;
}
}
}
}
第二种tsx部分
import { Component } from 'react'
import './index.scss'
export default class index extends Component {
state = { start: 0, move: 0, index: 0, arr: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }
componentDidUpdate() {
const { index } = this.state
;(this.refs.ul as HTMLDivElement).scrollLeft =
index > 0 && index < 7 ? 75 * index - 75 : index === 0 ? 0 : 375
}
render() {
const { start, move, index, arr } = this.state
return (
<div className='app'>
<div className='ul' ref={'ul'}>
<div className='ulSub'>
<div className='slide' style={{ left: 75 * index + 18 }}></div>
{arr.map((e, i) => (
<div className={index === i ? 'active' : ''} onTouchStart={(e) => this.setState({ index: i })}>
{e}
</div>
))}
</div>
</div>
<div
className='sub'
style={{ left: index * -375 }}
onTouchStart={(e) => this.setState({ start: e.changedTouches[0].pageX, move: 0 })}
onTouchMove={(e) => this.setState({ move: e.changedTouches[0].pageX - start })}
onTouchEnd={(e) => {
if (move > 50) index > 0 && this.setState({ index: index - 1 })
else if (move < -50) index < 9 && this.setState({ index: index + 1 })
}}
>
{arr.map((e) => (
<div>{e}</div>
))}
</div>
</div>
)
}
}
第二种scss部分
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.app {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
.sub {
position: relative;
width: 1000%;
height: 90vh;
display: flex;
transition: 0.6s;
div {
width: 100vw;
height: 100%;
text-align: center;
line-height: 100vh;
font-size: 100px;
}
}
.ul {
position: relative;
width: 100vw;
height: 10vh;
top: 0;
background-color: red;
overflow-x: scroll;
scroll-behavior: smooth;
&::-webkit-scrollbar {
display: none;
}
.ulSub {
position: relative;
transition: 0.6s;
width: 200vw;
height: 100%;
background-color: pink;
display: flex;
::-webkit-scrollbar {
display: none;
}
div {
width: 20vw;
height: 100%;
text-align: center;
line-height: 10vh;
}
.slide {
position: absolute;
width: 10vw;
height: 10px;
border-radius: 5px;
background-color: red;
top: 8vh;
z-index: 20;
transition: 0.1s;
}
.active {
font-weight: 700;
font-size: 30px;
}
}
}
}