美文网首页
2020-12-20

2020-12-20

作者: 码农私房菜 | 来源:发表于2020-12-19 15:40 被阅读0次

react 电商联动demo

import React, { FC, useEffect, useState } from 'react'
import './index.less'

interface IProps {
  datas: Array<IPropsDatas>;
  leftRow: (paramItem: IPropsItem) => JSX.Element;
  rightRow: (paramItem: IPropsItem) => JSX.Element;
  classNames?: string
}
interface IPropsItem {
  title: string;
  key: string;
}
interface IPropsDatas {
  left: Array<IPropsItem>;
  right: Array<IPropsItem>;
}

// const datas = [
//   { left: { title: 'AAA', key: 't1a' }, right: [{ title: 'AAA', key: 'AAA' }] },
// ]
// const leftRow = (paramItem: any) => (
//   <div className=''>{paramItem}</div>
// )
// const rightRow = (paramItem: any) => (
//   <div className=''>
//     {paramItem}
//     <div className=''>ceshi</div>
//   </div>
// )

let tabLeftInit: Array<IPropsItem[]> = [];
let tabRightInit: Array<IPropsItem[]> = [];

let right: number[] = []
let rightSum: number[] = []
let left: number[] = []
let leftSum: number[] = []
let newIndex: number = 0
let itemEleRight: any = null;
let itemEleLeft: any = null;
let listEleWrap: any = null;

const getEle = (ele: string) => {
  const itemHeiList: any = []
  const itemEle = document.querySelectorAll(ele)
  itemEle.forEach((item: any) => {
    itemHeiList.push(item.offsetHeight)
  })
  return itemHeiList
}

const getEleSum = (ele: number[]) => {
  const sumArr: number[] = []
  const sum = ele.reduce((total: number, num: number) => {
    const sumItem = total + num
    sumArr.push(sumItem)
    return sumItem
  }, 0)
  return sumArr
}

const AboutLinkage: FC<IProps> = (props: IProps): JSX.Element => {
  let { datas, leftRow, rightRow, classNames = '' } = props;

  const [stateIndex, setStateIndex] = useState(newIndex)
  const [tabLeft, setStateTabLeft] = useState(tabLeftInit)
  const [tabRight, setStateTabRight] = useState(tabRightInit)

  const splitList = (datas: Array<IPropsDatas>) => {
    const listL: Array<IPropsItem> = []
    const listR: Array<IPropsItem[]> = []
    datas.forEach((item: any) => {
      listL.push(item.left)
      listR.push(item.right)
    })
    setStateTabLeft([listL])
    setStateTabRight(listR)
  }

// 点击右侧滚动
const handleClick = (items: any, seat: any) => {
  let num = 0;
  if (items === newIndex) return
  newIndex = items
  for (let i = 0; i < items; i++) {
    num += right[i];
  }
if (itemEleRight.length > 0) {
  const el = itemEleRight[0]
  el && el.scrollTo({
     top: num,
     left: 0,
     behavior: "smooth"
   })
  }
}
// 渲染列表
const fnCreateList = (dataList: Array<IPropsItem[]>, seat?: string) => (
  <div className={`about-linkage-list-wrap${classNames && -classNames}`}>
    {dataList.map((item: IPropsItem[], index: number) => {
      return (
        <ul className={`about-linkage-list${classNames && -classNames}`} key={index} >
          {item.map((item: any, index: number) => (
            <li
              key={'' + index + seat}
              className={(stateIndex === index) && seat ?
              `about-linkage-item${classNames && -classNames} active${classNames && -classNames}` :
              `about-linkage-item${classNames && -classNames}`}
              onClick={() => {if (seat)  handleClick(index, 1)}}
            >
              <div className={`item-text${classNames && -classNames}`}>
                {
                  seat ?
                    leftRow && leftRow(item.title) :
                    rightRow && rightRow(item.title)
                }
                </div>
             </li>)
            )}
        </ul>
        )}
      )}
    </div>
  )

// 监听滚动事件
const onscroll = function () {
  let scollTopNumR = itemEleRight[0].scrollTop
  let keyR = rightSum.findIndex((item: number) => item > scollTopNumR) || 0
  if (keyR < 0) keyR = 0
  let keyLVal = leftSum[(keyR - 1)] || 0 // 左侧滚动标识位
  let keyLValNext = leftSum[(keyR)] || 0 // 左侧滚动判断标识位

  const numScrollSumR = scollTopNumR + itemEleRight[0].offsetHeight // 右侧滚动高度位置
  const numSumR = listEleWrap[1].offsetHeight// 左侧高度L
  if (numScrollSumR < numSumR) {
    setStateIndex(keyR)
    newIndex = keyR
  } // 左侧选中判断
  const elL = itemEleLeft[0]
  if (keyLValNext > elL.offsetHeight) {
    elL && elL.scrollTo({
      top: keyLVal - (elL.offsetHeight / 2),
      left: 0,
      behavior: "smooth"
    })
  }
  if ((keyLValNext < elL.offsetHeight) && (elL.scrollTop !== 0)) {
    elL && elL.scrollTo({
      top: 0,
      left: 0,
      behavior: "smooth"
    })
  }
}

useEffect(() => {
  datas && splitList(datas)
  setTimeout(() => {
    right = getEle(`.about-linkage-right${classNames && -classNames} .about-linkage-list${classNames && -  classNames}`)
    left = getEle(`.about-linkage-left${classNames && -classNames} .about-linkage-item${classNames && -classNames}`)
    rightSum = getEleSum(right)
    leftSum = getEleSum(left)
    itemEleRight = document.body.querySelectorAll(`.about-linkage-right${classNames && -classNames}`)
    itemEleLeft = document.body.querySelectorAll(`.about-linkage-left${classNames && -classNames}`)
    listEleWrap = document.body.querySelectorAll(`.about-linkage-list-wrap${classNames && -classNames}`)
  }, 0)
  return () => {
    // cleanup
    right = []
    rightSum = []
    left = []
    leftSum = []
    newIndex = 0
    itemEleRight = null;
    itemEleLeft = null;
    listEleWrap = null;
  }
}, [datas, classNames])

return (
  <div className={`about-linkage-wrap${classNames && -classNames}`}>
    <div className={`about-linkage-left-wrap${classNames && -classNames}`}>
      <div className={`about-linkage-left${classNames && -classNames}`}>
        {fnCreateList(tabLeft, '1')}
      </div>
    </div>
    <div
      className={`about-linkage-right${classNames && -classNames}`}
      onScroll={onscroll}
    >
      {fnCreateList(tabRight, '')}
    </div>
  </div>
 )
}

export default Demo

style

@width: 200px;
@height: 32vh;
@leftHeight: 100px;
@scrollBarWidth: 16px;
@flagWidth: 6px;

.about-linkage-wrap {
  width: 100%;
  height: @height;
  background: pink;
  position: relative;
  z-index: 2;
  .about-linkage-left-wrap {
    position: absolute;
    width: @width;
    overflow: hidden;
    position: absolute;
    left: 0;
    top: 0;
    z-index: 2;
   }
  .about-linkage-left {
    background: #bfa;
    padding-right: @scrollBarWidth;
    width: calc(@width + @scrollBarWidth);
    height: @height;
    overflow-y: scroll;
  }
  .about-linkage-right {
    position: absolute;
    left: 0;
    top: 0;
    padding-left: @width;
    width: 100%;
    height: @height;
    z-index: 1;
    overflow-y: scroll;
    &::-webkit-scrollbar {
      display: none;
    }
  }
}

.about-linkage-list-wrap {
  width: 100%;
  .about-linkage-list {
    width: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    .about-linkage-item {
      width: 100%;
      min-height: @leftHeight;
      display: flex;
      justify-content: flex-start;
      align-items: center;
      padding-right: @flagWidth;
      border:1px solid #ccc;
      .item-text {
        width: 100%;
        height: 100%;
      }
    }
    .active {
      color: #fff;
      background: pink;
    }
  }
}

相关文章

网友评论

      本文标题:2020-12-20

      本文链接:https://www.haomeiwen.com/subject/kylknktx.html