目录与锚点功能实现

123 阅读1分钟

视口监听

  useEffect(() => {
    const intersectionObserver = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting) {
          setActiveKey(entries[0].target.id);
        }
      },
      {
        root: document.getElementById(
          'contract-application-detail-content-main',
        ),
        threshold: 0,
        rootMargin: '-50% 0px -50% 0px',
      },
    );

    [
      CONTRACT_APPLICATION_DETAIL_CONTENT_APPLY_TITLE,
      CONTRACT_APPLICATION_DETAIL_CONTENT_FLOW_TITLE,
    ].forEach((key) => {
      intersectionObserver.observe(document.getElementById(key) as Element);
    });
  }, []);

tab切换 水平 or 垂直

  <Tabs
    items={items}
    border
    tabBarPaddingLeft={24}
    tabBarClassName="text-12"
    fontSizeChange={false}
    className="[&_.ant-tabs-ink-bar]:h-2px!"
    activeKey={activeKey}
    onChange={(val) => {
      const el = document.getElementById(val);
      if (el) {
        scrollIntoViewAndSmoooth(el);
      }
      setActiveKey(val);
    }}
  />

跳转锚点

// 丝滑滚动到目标 element
export function scrollIntoViewAndSmoooth(el: any, block = 'center') {
  el.scrollIntoView({
    behavior: 'smooth',
    block,
    inline: 'center',
  });
}

页面结构

    <div
      id="contract-application-detail-content-main"
      className="contract-application-detail-content-main pl-24px mt-16px"
    >
      {/* 申请意见  */}
      <div
        id={CONTRACT_APPLICATION_DETAIL_CONTENT_APPLY_TITLE}
        className="contract-application-detail-content-apply "
      >
        <div className="fontLinkMa-[#333_14_20_65]">申请意见</div>
        <div className="w-100% h-600px bg-emerald mt-30px"></div>
        {/* 插入组件 */}
      </div>
      {/* 流转意见 */}
      <div
        id={CONTRACT_APPLICATION_DETAIL_CONTENT_FLOW_TITLE}
        className="contract-application-detail-content-flow mt-50px"
      >
        <div className="fontLinkMa-[#333_14_20_65]">流转意见</div>
        <div className="mt-16px">
          <Timeline
            items={[
              {
                children: <OaFlowItem />,
              },
              {
                children: <OaFlowItem />,
              },
              {
                children: <OaFlowItem />,
              },
              {
                children: <OaFlowItem />,
              },
              {
                children: <OaFlowItem />,
              },
              {
                children: <OaFlowItem />,
              },
              {
                children: <OaFlowItem />,
              },
              {
                children: <OaFlowItem />,
              },
            ]}
          />
        </div>
      </div>
    </div>