固定位置边栏内容在 Bootstrap 模态关闭时移动
Position Fixed Sidebar Content Moves on Bootstrap Modal Close
我们有一个简单的 React 应用程序,带有一个基本的侧边栏和一个 bootstrap 模式。
这就是我们观察到奇怪行为的地方。如果我们单击“X”,我们的侧边栏会在页面上下降一会儿,直到模式关闭。
使用任何其他按钮或输入都不会观察到此行为。即使我们单击执行相同操作(关闭模式)的“关闭”按钮,边栏也不会移动。只有当我们在“X”上按下鼠标时它才会移动。
如果我在“X”上按下鼠标并将光标移开,然后向上移动鼠标,侧边栏将保持“下移”状态,直到我关闭模态框。
这很奇怪,我们不知道这里会发生什么,我们将不胜感激。
这里是 React 组件的代码:
import React, { useContext, useEffect, useState, FC } from 'react'
import { NavLink } from 'react-router-dom'
import { BoxSeam, House, Check2Circle, Download } from 'react-bootstrap-icons'
import { GlobalContext } from '../context/GlobalContext'
import Header from '../components/Header'
import Snackbar from '../components/Snackbar'
import SelectLocationModal from '../components/SelectLocationModal'
import IPropsWithChildren from '../ts/interfaces/IPropsWithChildren.interface'
import INavLink from '../ts/interfaces/INavLink.interface'
import styles from '../styles/layouts/Layout.module.scss'
const PrivateLayout: FC<IPropsWithChildren> = ({ children }) => {
// Sidebar default is closed below 768px screens & open on larger
// Therefore, isSidebarOpen is only an appropriate name for smaller screens
// On larger screens this would be interpreted as isSidebarClosed
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
const { location, setLocation } = useContext(GlobalContext);
const navLinks: INavLink[] = [
{
to: '/',
icon: <BoxSeam />,
displayText: 'Containers',
disabled: false
},
{
to: '/receiving',
icon: <Download />,
displayText: "Receiving",
disabled: false
},
{
to: '/approve',
icon: <Check2Circle />,
displayText: "Approve",
disabled: false
}
]
const closeOnSmScreen = () => {
setIsSidebarOpen(false);
}
useEffect(() => {
const location = localStorage.getItem('LocationID');
if (location) {
setLocation(location);
}
}, [setLocation])
return (
<div>
<SelectLocationModal
isOpen={location === ''}
handleClose={() => null}
/>
<Header
setIsSidebarOpen={setIsSidebarOpen}
isSidebarOpen={isSidebarOpen}
/>
<div className={styles.wrapper}>
<nav className={`${styles.sidebar} ${isSidebarOpen ? styles.active : ''} bg-light`}>
<div className={styles.sidebarContent}>
<ul className="ps-0">
{
navLinks.map((navLink, i) => (
<li key={i}>
<NavLink
to={ navLink.to }
activeClassName={ navLink.disabled ? '' : styles.activeLink }
className={`${navLink.disabled ? styles.disabledLink : ''} d-flex align-items-center flex-md-column py-2 navLink`}
onClick={closeOnSmScreen}
exact
>
{navLink.icon}
<span>{navLink.displayText}</span>
</NavLink>
</li>
))
}
</ul>
</div>
</nav>
<div className={"childrenContainer container"}>
{children}
<Snackbar />
</div>
</div>
</div>
)
}
export default PrivateLayout
和 CSS:
@import '../variables.scss';
.childrenContainer {
padding-top: $headerHeight;
}
.activeLink {
color: white !important;
background-color: $primary;
}
// Sidebar
.wrapper {
display: flex;
align-items: stretch;
width: 100%;
}
.sidebar {
position: fixed;
top: $headerHeight;
z-index: 999;
min-width: 85vw;
min-height: calc(100vh - #{$headerHeight});
margin-left: -85vw;
transition: .2s ease-in;
}
.sidebar.active {
margin-left: 0;
box-shadow: 2px 0px 15px 0px #000;
}
.sidebarContent {
position: sticky;
li {
list-style: none;
a {
text-decoration: none;
color: var(--dark);
}
}
}
.disabledLink {
text-decoration: line-through !important;
}
.navLink {
padding-left: 1rem;
span {
padding-left: .5rem;
}
svg {
height: 1.25rem;
width: 1.25rem;
}
}
@media screen and (min-width:768px) {
.childrenContainer {
padding-top: $headerLgHeight;
}
.sidebar {
position: sticky;
padding-top: $headerLgHeight;
margin-left: 0;
max-width: $sidebarWidth;
min-width: $sidebarWidth;
height: 100vh;
}
.sidebar.active {
margin-left: -$sidebarWidth;
box-shadow: none;
background: white !important;
}
.sidebarContent {
position: fixed;
width: $sidebarWidth;
}
.navLink {
display: flex;
flex-direction: column;
align-items: center;
padding-left: 0;
span {
padding-left: 0;
font-size: .67rem;
}
svg {
height: 1.25rem;
width: 1.25rem;
}
}
}
这是一个重现上述行为的 code snadbox(感谢 Igor Gonak 发起此活动)。
只需删除“top”,它就会停止翻转:
.sidebar {
position: fixed;
// top: $headerHeight;
z-index: 999;
min-width: 85vw;
min-height: calc(100vh - #{$headerHeight});
margin-left: -85vw;
transition: .2s ease-in;
}
我们有一个简单的 React 应用程序,带有一个基本的侧边栏和一个 bootstrap 模式。
如果我在“X”上按下鼠标并将光标移开,然后向上移动鼠标,侧边栏将保持“下移”状态,直到我关闭模态框。
这很奇怪,我们不知道这里会发生什么,我们将不胜感激。
这里是 React 组件的代码:
import React, { useContext, useEffect, useState, FC } from 'react'
import { NavLink } from 'react-router-dom'
import { BoxSeam, House, Check2Circle, Download } from 'react-bootstrap-icons'
import { GlobalContext } from '../context/GlobalContext'
import Header from '../components/Header'
import Snackbar from '../components/Snackbar'
import SelectLocationModal from '../components/SelectLocationModal'
import IPropsWithChildren from '../ts/interfaces/IPropsWithChildren.interface'
import INavLink from '../ts/interfaces/INavLink.interface'
import styles from '../styles/layouts/Layout.module.scss'
const PrivateLayout: FC<IPropsWithChildren> = ({ children }) => {
// Sidebar default is closed below 768px screens & open on larger
// Therefore, isSidebarOpen is only an appropriate name for smaller screens
// On larger screens this would be interpreted as isSidebarClosed
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
const { location, setLocation } = useContext(GlobalContext);
const navLinks: INavLink[] = [
{
to: '/',
icon: <BoxSeam />,
displayText: 'Containers',
disabled: false
},
{
to: '/receiving',
icon: <Download />,
displayText: "Receiving",
disabled: false
},
{
to: '/approve',
icon: <Check2Circle />,
displayText: "Approve",
disabled: false
}
]
const closeOnSmScreen = () => {
setIsSidebarOpen(false);
}
useEffect(() => {
const location = localStorage.getItem('LocationID');
if (location) {
setLocation(location);
}
}, [setLocation])
return (
<div>
<SelectLocationModal
isOpen={location === ''}
handleClose={() => null}
/>
<Header
setIsSidebarOpen={setIsSidebarOpen}
isSidebarOpen={isSidebarOpen}
/>
<div className={styles.wrapper}>
<nav className={`${styles.sidebar} ${isSidebarOpen ? styles.active : ''} bg-light`}>
<div className={styles.sidebarContent}>
<ul className="ps-0">
{
navLinks.map((navLink, i) => (
<li key={i}>
<NavLink
to={ navLink.to }
activeClassName={ navLink.disabled ? '' : styles.activeLink }
className={`${navLink.disabled ? styles.disabledLink : ''} d-flex align-items-center flex-md-column py-2 navLink`}
onClick={closeOnSmScreen}
exact
>
{navLink.icon}
<span>{navLink.displayText}</span>
</NavLink>
</li>
))
}
</ul>
</div>
</nav>
<div className={"childrenContainer container"}>
{children}
<Snackbar />
</div>
</div>
</div>
)
}
export default PrivateLayout
和 CSS:
@import '../variables.scss';
.childrenContainer {
padding-top: $headerHeight;
}
.activeLink {
color: white !important;
background-color: $primary;
}
// Sidebar
.wrapper {
display: flex;
align-items: stretch;
width: 100%;
}
.sidebar {
position: fixed;
top: $headerHeight;
z-index: 999;
min-width: 85vw;
min-height: calc(100vh - #{$headerHeight});
margin-left: -85vw;
transition: .2s ease-in;
}
.sidebar.active {
margin-left: 0;
box-shadow: 2px 0px 15px 0px #000;
}
.sidebarContent {
position: sticky;
li {
list-style: none;
a {
text-decoration: none;
color: var(--dark);
}
}
}
.disabledLink {
text-decoration: line-through !important;
}
.navLink {
padding-left: 1rem;
span {
padding-left: .5rem;
}
svg {
height: 1.25rem;
width: 1.25rem;
}
}
@media screen and (min-width:768px) {
.childrenContainer {
padding-top: $headerLgHeight;
}
.sidebar {
position: sticky;
padding-top: $headerLgHeight;
margin-left: 0;
max-width: $sidebarWidth;
min-width: $sidebarWidth;
height: 100vh;
}
.sidebar.active {
margin-left: -$sidebarWidth;
box-shadow: none;
background: white !important;
}
.sidebarContent {
position: fixed;
width: $sidebarWidth;
}
.navLink {
display: flex;
flex-direction: column;
align-items: center;
padding-left: 0;
span {
padding-left: 0;
font-size: .67rem;
}
svg {
height: 1.25rem;
width: 1.25rem;
}
}
}
这是一个重现上述行为的 code snadbox(感谢 Igor Gonak 发起此活动)。
只需删除“top”,它就会停止翻转:
.sidebar {
position: fixed;
// top: $headerHeight;
z-index: 999;
min-width: 85vw;
min-height: calc(100vh - #{$headerHeight});
margin-left: -85vw;
transition: .2s ease-in;
}