首页 > 解决方案 > 当 AppBar 在 div 内时,如何使 AppBar 隐藏并显示在滚动条上?

问题描述

在 div 中有一个 AppBar,我想在向下滚动时隐藏它并在向上滚动时重新出现。

https://i.stack.imgur.com/WF5Jb.png

这是我的看法,使用https://material-ui.com/components/app-bar/#hide-app-bar

export default function HideAppBar(props) {
  return (
    <React.Fragment>
      <div style={{ height: "100px", width: "100px", overflow: "auto" }}>
        {" "}
        External content
      </div>
      <CssBaseline />
      <div style={{ height: "400px", width: "300px", overflow: "auto" }}>
        <HideOnScroll {...props}>
          <AppBar style={{ position: "inherit" }}>
            <Toolbar>
              <Typography variant="h6">Scroll to Hide App Bar</Typography>
            </Toolbar>
          </AppBar>
        </HideOnScroll>

        <Toolbar />
        <Container>
          <Box my={2}>
            {[...new Array(12)]
              .map(
                () => `Cras mattis consectetur purus sit amet fermentum.
Cras justo odio, dapibus ac facilisis in, egestas eget quam.
Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
Praesent commodo cursus magna, vel scelerisque nisl consectetur et.`
              )
              .join("\n")}
          </Box>
        </Container>
      </div>
    </React.Fragment>
  );

https://codesandbox.io/s/material-demo-d0p7p?file=/demo.js:0-2169

当您向上滚动时,AppBar 不会再次显示,除非您一直回到顶部。

标签: javascriptcssreactjsmaterial-ui

解决方案


这个问题的关键是

  • 在我们的这个特定 div 内有一个滚动事件监听器
  • 检查滚动是向上还是向下(我们通过比较scrollPosition我们的状态来做到这一点)
  • 控制 css 显示/隐藏 AppBar

相关JS

import React, { useState, useEffect } from "react";
import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";
import Typography from "@material-ui/core/Typography";
import CssBaseline from "@material-ui/core/CssBaseline";
import Box from "@material-ui/core/Box";
import Container from "@material-ui/core/Container";

export default function HideAppBar(props) {
  const [scrollPosition, setScrollPosition] = useState(0);
  const [showBar, setShowBar] = useState(false);

  useEffect(() => {
    document
      .getElementById("insideDiv")
      .addEventListener("scroll", handleScroll);
  });

  const handleScroll = event => {
    const newScrollPosition = event.target.scrollTop;
    setScrollPosition(newScrollPosition);
    if (scrollPosition && scrollPosition > newScrollPosition) {
      setShowBar(true);
    } else {
      setShowBar(false);
    }
  };

  return (
    <React.Fragment>
      <div style={{ height: "100px", width: "100px", overflow: "auto" }}>
        {" "}
        External content
      </div>
      <CssBaseline />
      showBar? {showBar.toString()}
      <div
        id="insideDiv"
        style={{ height: "400px", width: "300px", overflow: "auto" }}
      >
        <AppBar
          style={
            showBar
              ? {
                  position: "absolute",
                  top: "120px",
                  width: "280px",
                  left: "0"
                }
              : { position: "inherit" }
          }
        >
          <Toolbar>
            <Typography variant="h6">Scroll to Hide App Bar</Typography>
          </Toolbar>
        </AppBar>

        <Toolbar />
        <Container>
          <Box my={2}>
            {[...new Array(12)]
              .map(
                () => `Cras mattis consectetur purus sit amet fermentum.
Cras justo odio, dapibus ac facilisis in, egestas eget quam.
Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
Praesent commodo cursus magna, vel scelerisque nisl consectetur et.`
              )
              .join("\n")}
          </Box>
        </Container>
      </div>
      Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus
      ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur
      ac, vestibulum at eros. Praesent commodo cursus magna, vel scelerisque
      nisl consectetur e Cras mattis consectetur purus sit amet fermentum. Cras
      justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus,
      porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus
      magna, vel scelerisque nisl consectetur e Cras mattis consectetur purus
      sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget
      quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
      Praesent commodo cursus magna, vel scelerisque nisl consectetur e Cras
      mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac
      facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac,
      vestibulum at eros. Praesent commodo cursus magna, vel scelerisque nisl
      consectetur e
    </React.Fragment>
  );
}

分叉和更新的代码框在这里


推荐阅读