React+ts realizes secondary linkage effect

React+ts realizes secondary linkage effect

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:
  • Implementation of TypeScript in React project
  • Summary of the use of TypeScript in React projects
  • TypeScript generic parameter default types and new strict compilation option
  • Step by step guide to build a calendar component with React
  • Practical tips for TS type filtering in front-end React Nextjs

<<:  Docker image cannot be deleted Error: No such image: xxxxxx solution

>>:  Summary of common Nginx techniques and examples

Recommend

Practical record of vue using echarts word cloud chart

echarts word cloud is an extension of echarts htt...

Analysis of the principle and usage of MySQL continuous aggregation

This article uses examples to illustrate the prin...

The concrete implementation of JavaScript exclusive thinking

In the previous blog, Xiao Xiong updated the meth...

Use of kubernetes YAML files

Table of contents 01 Introduction to YAML files Y...

Sample code for implementing a background gradient button using div+css3

As the demand for front-end pages continues to in...

Example operation MySQL short link

How to set up a MySQL short link 1. Check the mys...

How to use video.js in vue to play m3u8 format videos

Table of contents 1. Installation 2. Introducing ...

Vue component library ElementUI implements table loading tree data tutorial

ElementUI implements a table tree list loading tu...

Teach you how to deploy zabbix service on saltstack

Table of contents Saltstack deploys zabbix servic...

Disabled values ​​that cannot be entered cannot be passed to the action layer

If I want to make the form non-input-capable, I se...

js to achieve the pop-up effect

This article example shares the specific code of ...

How to install and persist the postgresql database in docker

Skip the Docker installation steps 1. Pull the po...