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
Table of contents Preface Features of Vue Native ...
echarts word cloud is an extension of echarts htt...
HTML tag: superscript In HTML, the <sup> tag...
This article uses examples to illustrate the prin...
In the previous blog, Xiao Xiong updated the meth...
Why is the title of the article “Imitation Magnif...
Table of contents 01 Introduction to YAML files Y...
As the demand for front-end pages continues to in...
How to set up a MySQL short link 1. Check the mys...
Table of contents 1. Installation 2. Introducing ...
ElementUI implements a table tree list loading tu...
Table of contents Saltstack deploys zabbix servic...
If I want to make the form non-input-capable, I se...
This article example shares the specific code of ...
Skip the Docker installation steps 1. Pull the po...