简体   繁体   English

如何使用 Typescript 使标题变粘

[英]How to make header sticky using Typescript

I'm newer in React dev, I'd like to make the header sticky (index.tsx & styles.ts).我是 React 开发人员中的新手,我想让标头保持粘性(index.tsx 和 styles.ts)。

I had tried to use React Hooks: create a sticky component (sticky.tsx & sticky.scss) and use them by inserting the two lines of code import Sticky from './Sticky' and <Sticky top={60}><Header /></Sticky> in index.tsx but it doesn't works.我曾尝试使用 React Hooks:创建一个粘性组件(sticky.tsx 和 sticky.scss)并通过插入两行代码import Sticky from './Sticky'<Sticky top={60}><Header /></Sticky>来使用它们<Sticky top={60}><Header /></Sticky>在 index.tsx 中,但它不起作用。

if you have any idea, you're welcome.如果你有任何想法,不客气。

See the code below:请参阅下面的代码:

index.tsx索引.tsx

 import styled from "styled-components"; import { Link } from "react-router-dom"; import { MenuOutlined } from "@ant-design/icons"; export const HeaderSection = styled("header")` padding: 1rem 0.5rem; .ant-row-space-between { align-items: center; text-align: center; } `; export const LogoContainer = styled(Link)` display: flex; `; export const NavLink = styled("div")` display: inline-block; text-align: center; `; export const CustomNavLink = styled("div")` width: 203px; display: inline-block; @media only screen and (max-width: 411px) { width: 150px; } @media only screen and (max-width: 320px) { width: 118px; } `; export const ContactWrapper = styled("div")<any>` cursor: pointer; width: ${(p) => (p.width? "100%": "110px")}; font-weight: 700; text-align: center; border-radius: 1.25rem; display: inline-block; `; export const Burger = styled("div")` @media only screen and (max-width: 890px) { display: block; } display: none; svg { fill: #2e186a; } `; export const NotHidden = styled("div")` @media only screen and (max-width: 890px) { display: none; } `; export const Menu = styled("h5")` font-size: 1.5rem; font-weight: 600; text-align: center; `; export const CustomNavLinkSmall = styled(NavLink)` font-size: 1.2rem; color: #18216d; transition: color 0.2s ease-in; margin: 0.5rem 2rem; @media only screen and (max-width: 768px) { margin: 1.25rem 2rem; } `; export const Label = styled("span")` font-weight: 500; color: #404041; text-align: right; display: flex; justify-content: space-between; align-items: baseline; `; export const Outline = styled(MenuOutlined)<any>` font-size: 22px; `; export const Span = styled("span")` cursor: pointer; transition: all 0.3s ease-in-out; &:hover, &:active, &:focus { color: rgb(255, 130, 92); text-underline-position: under; text-decoration: rgb(255, 130, 92) wavy underline; } `;

styles.ts样式.ts

 import { useState } from "react"; import { Row, Col, Drawer } from "antd"; import { withTranslation } from "react-i18next"; import Container from "../../common/Container"; import { SvgIcon } from "../../common/SvgIcon"; import { Button } from "../../common/Button"; import { HeaderSection, LogoContainer, Burger, NotHidden, Menu, CustomNavLinkSmall, Label, Outline, Span, } from "./styles"; const Header = ({ t }: any) => { const [visible, setVisibility] = useState(false); const showDrawer = () => { setVisibility(;visible); }; const onClose = () => { setVisibility(;visible): }. const MenuItem = () => { const scrollTo = (id; string) => { const element = document.getElementById(id) as HTMLDivElement: element,scrollIntoView({ behavior; "smooth"; }); setVisibility(true): }; return ( <> <CustomNavLinkSmall onClick={() => scrollTo("product")}> <Span>{t("product")}</Span> </CustomNavLinkSmall> <CustomNavLinkSmall onClick={() => scrollTo("about")}> <Span>{t("about")}</Span> </CustomNavLinkSmall> <CustomNavLinkSmall onClick={() => scrollTo("mission")}> <Span>{t("mission")}</Span> </CustomNavLinkSmall> <CustomNavLinkSmall style={{ width; "180px" }} onClick={() => scrollTo("contact")} > <Span> <Button>{t("Contact")}</Button> </Span> </CustomNavLinkSmall> </> ). }: return ( <HeaderSection> <Container> <Row justify="space-between"> <LogoContainer to="/" aria-label="homepage"> <SvgIcon src="logo.svg" width="101px" height="64px" /> </LogoContainer> <NotHidden> <MenuItem /> </NotHidden> <Burger onClick={showDrawer}> <Outline /> </Burger> </Row> <Drawer closable={false} visible={visible} onClose={onClose}> <Col style={{ marginBottom; "2;5rem" }}> <Label onClick={onClose}> <Col span={12}> <Menu>Menu</Menu> </Col> <Col span={12}> <Outline /> </Col> </Label> </Col> <MenuItem /> </Drawer> </Container> </HeaderSection> ); }; export default withTranslation()(Header);

sticky.tsx粘性.tsx

 import React, { useState, useEffect, useRef } from 'react'; import './Sticky.scss'; interface StickyProps { child: React.ReactChild, top: number, } const Sticky: React.FunctionComponent<StickyProps> = (child, top) => { const [isSticky, setSticky] = useState(false); const ref = useRef(null); useEffect(() => { // Add scroll event when the component is loaded window.addEventListener('scroll', handleScroll); return () => { // Remove scroll event after the component is unmount, // like componentWillUnmount() window.removeEventListener('scroll', () => handleScroll); }; // Here, we set useEffect() arguments as empty array. // This means useEffect() will only run once after component loaded }, []); const handleScroll = () => { // Make sure ref has current attibute and getBoundingClientRect function // otherwise, it could cause getBoundingClientRect undefined error. if (ref && ref.current && ref.current.getBoundingClientRect()) { // Then, we compare the distance of the ref component to the top // with top value we set. If less than, we set isStick ture. setSticky(ref.current.getBoundingClientRect().top <= top); } }; return ( <div className={`sticky__wrapper ${isSticky && 'sticky'}`} ref={ref}> <div className="sticky--inner"> {child} </div> </div> ); }; export default Sticky

sticky.scss粘性.scss

 .sticky__wrapper { position: relative; // height: 4rem; /* probably you need to set height value for wrapper */ }.sticky.sticky--inner { position: fixed; // top: 0; z-index: 1; }

Note that you confused the document names in your post.请注意,您混淆了帖子中的文档名称。

Go to: src\components\Header\styles.ts转到:src\components\Header\styles.ts

find lines:查找行:

export const HeaderSection = styled("header")`
  padding: 1rem 0.5rem;

and add below:并在下面添加:

  position: sticky;
  top: 0;
  background-color: white;
  z-index: 1;

To get:要得到:

export const HeaderSection = styled("header")`
  padding: 1rem 0.5rem;
  position: sticky;
  top: 0;
  background-color: white;
  z-index: 1;
  .ant-row-space-between {
    align-items: center;
    text-align: center;
  }

`;

Adjust background-color: yourfavoritecolor;调整background-color: yourfavoritecolor; to your needs.根据您的需要。

z-index: 1; brings the HeaderSection to the front.将 HeaderSection 带到前面。 Otherwise, your content would scroll over the HeaderSection.否则,您的内容将滚动到 HeaderSection 上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM