This article shares the specific code of React+ts to achieve the secondary linkage effect for your reference. The specific content is as follows .tsx files import { Component, createRef} from 'react' import './index.less' interface State { top: any ButtonList: Button[] ContentList: Content[] ButtonIndex: number } interface Button { id: string text: string } interface Content { id: string text: string height: number top: number } interface Props { } class Stairs extends Component<Props, State>{ LeftList: Button[] RightList: Content[] kaiguan: boolean right = createRef<HTMLDivElement>() left = createRef<HTMLDivElement>() LeftTex = createRef<HTMLDivElement>() // oTop: number | undefined viewHeight: number | undefined offHeight: number | undefined Lefttext = createRef<HTMLDivElement>() top: number | undefined oTop: number | undefined constructor(props: Props) { super(props) this.state = { ButtonList: [], ContentList: [], ButtonIndex: 0, top: 0 } this.LeftList = [] this.RightList = [] this.kaiguan = true this.oTop = 0 } componentDidMount() { this.BtnList(20) this.ConList(20) this.setState({ ButtonList: this.LeftList, ContentList: this.RightList }) } getRandom(m: number, n: number): number { return parseInt(`${Math.random() * (m - n) + n}`); } BtnList(n: number) { for (let i = 0; i < n; i++) { this.LeftList.push({ id: `a${i}`, text: `Button${i}`, }); } } ConList(n: number) { let ConTop = 0; for (let i = 0; i < n; i++) { let RandomHeight = this.getRandom(736, 1400); this.RightList.push({ id: `b${i}`, text: `Title${i}`, height: RandomHeight, top: ConTop, }); ConTop += RandomHeight; } } FnScroll() { // console.log(11) if (this.right.current) { this.oTop = this.right.current.scrollTop; if (this.kaiguan) { // console.log(111) let count = 0 for (var i = 0; i < this.state.ContentList.length; i++) { if (this.oTop >= this.state.ContentList[i].top) { count = i } this.setState({ ButtonIndex: count }) } // console.log(ButtonIndex,count) } } // eslint-disable-next-line if (this.oTop == this.state.ContentList[this.state.ButtonIndex].top) { this.kaiguan = true; } } Fn(index: any, ev: React.MouseEvent<HTMLDivElement>) { this.viewHeight = document.documentElement.clientHeight / 2 let target = ev.target as HTMLDivElement this.offHeight = target.offsetTop // console.log(this.offHeight) if (this.offHeight > this.viewHeight) { if (this.LeftTex.current) { this.LeftTex.current.scrollTo({ top: this.offHeight - this.viewHeight - target.clientHeight / 2, behavior: "smooth", }) } // console.log(this.LeftTex.current) } // console.log(this.offHeight - this.viewHeight - target.clientHeight / 2) this.kaiguan = false; // this.offHeight = ev.target.offsetTop // console.log(ev.target) if (this.right.current) { this.right.current.scroll({ top: this.RightList[index].top, behavior: "smooth", }); } this.setState({ ButtonIndex: index }) } ButtonIndex(index: number) { if (index >= 3) { if (this.left.current && this.Lefttext.current) { this.left.current.scrollTop = (index - 3) * this.Lefttext.current.offsetHeight; } } if (index < 3) { if (this.left.current) { this.left.current.scrollTop = 0; } } this.setState({ ButtonIndex: index }) } render() { let footList = this.state.ButtonList return ( <div> <div className="about"> <div className="scroll"> <div className="box1" ref="box1"></div> <div className="box2" ref="box2"></div> <div className="scroll-con" ref="scroll-con"> <div className="left" ref={this.LeftTex}> <div className="left-con"> {footList.map((item, index) => <div onClick={this.Fn.bind(this, index)} ref={this.Lefttext} className={this.state.ButtonIndex === index ? "ac left-txt" : "left-txt"} key={item.id} > {item.text} </div> )} </div> </div> <div className="right" ref={this.right} onScroll={this.FnScroll.bind(this)}> <div className="right-con"> <div className="right-txt" ref="right-txt"> {this.state.ContentList.map((item) => <div style={{ height: item.height }} className="right-title" key={item.id}>{item.text} </div> )} </div> </div> </div> </div> </div> </div> </div> ) } } export default Stairs .less files .scroll { width: 100vw; height: 100vh; overflow-y: scroll; .box1 { height: 300px; background: #000; width: 100%; } .box2 { height: 200px; background: tomato; width: 100%; } .box3 { position: -webkit-sticky; position: sticky; top: 0; height: 100px; background: palevioletred; z-index: 999; width: 100%; } .scroll-con { width: 100vw; height: 100vh; position: -webkit-sticky; position: sticky; top: 100px; display: flex; .left, .right { height: 100vh; overflow-y: scroll; } .left { width: 20vw; .left-txt { width: 20vw; height: 100px; text-align: center; line-height: 100px; background: red; } .left-txt.ac { background: lightcoral; z-index: 999; } } .right { width: 80vw; .right-title { width: 100%; height: 5vh; background: darkblue; color: aqua; line-height: 5vh; } } } } Finally, add the folder you defined to the route The effect diagram is as follows The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM. You may also be interested in:
|
<<: Docker image cannot be deleted Error: No such image: xxxxxx solution
>>: Summary of common Nginx techniques and examples
introduce A chart is a graphical representation o...
Table of contents Water wave effect Let's see...
This article shares the specific code of Vue+ssh ...
I was watching Tik Tok some time ago and thought ...
This article shares the specific code of jQuery t...
This article introduces the sample code of CSS to...
Table of contents Million-level data processing s...
Experimental environment A minimally installed Ce...
Table of contents A JSON is built on two structur...
Use CSS3 to animate the input box similar to the ...
The scroll-view of WeChat applet has more bugs wh...
First, let me explain the application method. The...
In order to solve the problem mentioned last time...
The search performance from fastest to slowest is...
I recently read about vue. I found a single-file ...