react-hook代码:
tsx:
import React, { useEffect, useRef } from "react";
import './index.less'
export default function Index() {
let list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
let lists = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
let left = useRef<HTMLDivElement>(null)
let right = useRef<HTMLDivElement>(null)
const getleft = () => left.current as HTMLDivElement
const getright = () => right.current as HTMLDivElement
useEffect(() => {
getleft().children[0].children[0].className = 'yes'
getright().onscroll = fnScroll
})
const fnScroll = () => {
let k = 0
let arrList = getright().children[0].childNodes
arrList.forEach(item => {
if ((item as HTMLDivElement).getBoundingClientRect().top < 0) k++
})
let p = k
if (p >= 1) p--
for (var i = 0; i < getleft().children[0].childNodes.length; i++) {
(getleft().children[0].children[i] as HTMLDivElement).className = ''
}
(getleft().children[0].children[p] as HTMLDivElement).className = 'yes'
if (p > 5) {
getleft().scrollTo({ top: (p - 5) * 42, behavior: 'smooth' })
} else {
getleft().scrollTo({ top: 0, behavior: 'smooth' })
}
}
const FnStart = (index: number) => {
let rightTop = getright().children[0].children[index].getBoundingClientRect().top
let rightTopZero = -getright().children[0].children[0].getBoundingClientRect().top
getright().scrollTo({ top: rightTopZero + rightTop + 1, behavior: 'smooth' })
}
return (
<div className="linkage-box">
<div className="left" ref={left}>
<div>
{
list.map((item, index) =>
<div key={index} onClick={() => FnStart(index)}>{item}</div>
)
}
</div>
</div>
<div className="right" ref={right}>
<div>
{
lists.map((item, index) =>
<div key={index}>{item}</div>
)
}
<div className="leftBottom"></div>
</div>
</div>
</div>
)
}
less:
.linkage-box {
width: 100vw;
height: 98vh;
display: flex;
div::-webkit-scrollbar {
display: none;
}
.left {
width: 250px;
display: flex;
flex-direction: column;
overflow-y: scroll;
>div {
>div {
height: 100px;
margin-bottom: 3px;
background-color: aqua;
}
>.yes {
background-color: red;
}
}
}
.right {
width: 500px;
display: flex;
flex-direction: column;
overflow-y: scroll;
// transition: .3s all;
>div {
// transition: .3s all;
>div {
height: 1600px;
margin-bottom: 3px;
background-color: pink;
}
>div:nth-child(2n) {
height: 1600px;
margin-bottom: 3px;
background-color: yellow;
}
.leftBottom {
width: 100%;
height: 1px;
}
}
}
}
vue3.0代码
<template>
<div class="slinkage">
<div class="left" ref="left">
<div class="left-scroll">
<div v-for="(item,index) in arr" :key="index" :class="index===i?'a':''" @touchstart="cut(index)">{{item}}</div>
</div>
</div>
<div class="right" ref="right" @scroll="fnscroll" @touchend="fnend">
<div class="right-scroll">
<div v-for="(item,index) in arr" :key="index">{{item}}</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from "@vue/reactivity"
const arr = ref<number[]>([1,2,3,4,5,6,7,8,9,10,11])
let i = ref<number>(0)
let state = ref<boolean>(true)
let left = ref<HTMLDivElement>(null)
let right = ref<HTMLDivElement>(null)
const getleft = ()=>left.value as HTMLDivElement
const getright = ()=>right.value as HTMLDivElement
const cut = (index:number)=>{
state.value = false
i.value = index
getright().scrollTop= index*getright().children[0].clientHeight
getleft().scrollTop = index>=4?(index-3)*100:0
}
const fnscroll = ()=>{
if(state.value ===false)return
let Index = Math.trunc(getright().scrollTop/getright().children[0].clientHeight)
i.value = Index
getleft().scrollTop = Index>=4?(Index-3)*100:0
}
const fnend = ()=>{
state.value = true
}
</script>
<style lang="less" scoped>
.slinkage{
display: flex;
.left{
overflow-y: scroll;
height: 100vh;
scroll-behavior: smooth;
.left-scroll{
height: 100vh;
div{
width: 10vw;
height: 15vh;
border: 1px solid #000;
}
.a{
background: linear-gradient(rgb(28, 186, 89),#b6b);
}
}
}
.right{
overflow-y: scroll;
height: 100vh;
scroll-behavior: smooth;
.right-scroll{
height: 100vh;
div{
width: 89vw;
height: 100vh;
background: linear-gradient(#f55,#b6b);
line-height: 100vh;
font-size: 500px;
}
}
}
.left::-webkit-scrollbar{
display: none;
}
.right::-webkit-scrollbar{
display: none;
}
}
</style>