React+ts實(shí)現(xiàn)二級(jí)聯(lián)動(dòng)效果
更新時(shí)間:2022年04月26日 09:51:04 作者:博-軒
這篇文章主要為大家詳細(xì)介紹了React+ts實(shí)現(xiàn)二級(jí)聯(lián)動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
本文實(shí)例為大家分享了React+ts實(shí)現(xiàn)二級(jí)聯(lián)動(dòng)效果的具體代碼,供大家參考,具體內(nèi)容如下
.tsx文件
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: `按鈕${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: `標(biāo)題${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文件
.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; } } } }
最后把自己定義的文件夾添加到路由里即可
效果圖如下
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
React創(chuàng)建組件的三種方式及其區(qū)別
本文主要介紹了React創(chuàng)建組件的三種方式及其區(qū)別,具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-01-01詳解React項(xiàng)目如何修改打包地址(編譯輸出文件地址)
這篇文章主要介紹了詳解React項(xiàng)目如何修改打包地址(編譯輸出文件地址),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-03-03React Native 搭建開發(fā)環(huán)境的方法步驟
本篇文章主要介紹了React Native 搭建開發(fā)環(huán)境的方法步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10React使用高德地圖的實(shí)現(xiàn)示例(react-amap)
這篇文章主要介紹了React使用高德地圖的實(shí)現(xiàn)示例(react-amap),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04