美文网首页
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