Skip to content

Commit

Permalink
🐛 fix(custom): 修复查看图片页面闪动问题
Browse files Browse the repository at this point in the history
当点击图片时,滚动条会被隐藏导致整体页面重拍;现在已经修复
  • Loading branch information
master1lan committed Feb 19, 2023
1 parent 6f4788a commit 26f8a26
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/routers/photo/item/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { PhotoSlider } from "react-photo-view";
import "react-photo-view/dist/react-photo-view.css";
import { useEffect } from "react";
import { useLocation } from "react-router-dom";
import { useBodyScrollHide } from "@utils/hooks/match";
type ModalType = {
images: basicImageType[];
open: boolean;
Expand All @@ -29,6 +30,7 @@ export default function ImgModals(props: ModalType) {
};
}
}, [open]);
useBodyScrollHide(open);
return (
<PhotoSlider
images={images.map((item, index) => ({ src: item.src, key: index }))}
Expand Down
71 changes: 71 additions & 0 deletions src/utils/dom/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* 给元素style添加属性。
*/
export const ObjectToHtmlStyle = (
obj: React.CSSProperties,
ele: HTMLElement
) => {
Object.entries(obj).forEach(([key, value]) => {
if (value) {
//@ts-ignore
ele.style[key] = value;
}
});
};

let _ScrollBarWidthCached: number | null = null;

function hasScrollbar(): boolean {
return (
document.body.scrollHeight >
(window.innerHeight || document.documentElement.clientHeight)
);
}
export function getScrollBarSize(): number {
if (!hasScrollbar()) {
_ScrollBarWidthCached = 0;
}
if (typeof _ScrollBarWidthCached === "number") {
return _ScrollBarWidthCached;
}
const inner = document.createElement("div");
ObjectToHtmlStyle(
{
width: "100%",
height: "200px",
},
inner
);
const outer = document.createElement("div");
ObjectToHtmlStyle(
{
position: "absolute",
top: "0",
left: "0",
pointerEvents: "none",
visibility: "hidden",
width: "200px",
height: "150px",
overflow: "hidden",
},
outer
);
outer.appendChild(inner);
document.body.appendChild(outer);
const widthContained = inner.offsetWidth;
ObjectToHtmlStyle(
{
overflow: "scroll",
},
outer
);
let widthScroll = inner.offsetWidth;

if (widthContained === widthScroll) {
widthScroll = outer.clientWidth;
}

document.body.removeChild(outer);
_ScrollBarWidthCached = widthContained - widthScroll;
return _ScrollBarWidthCached;
}
17 changes: 17 additions & 0 deletions src/utils/hooks/match.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Breakpoint, useMediaQuery, useTheme } from "@mui/material";
import { getScrollBarSize } from "@utils/dom";
import { useEffect } from "react";

/**
* @description 获知当前屏幕处于哪种大小
Expand All @@ -16,3 +18,18 @@ export const useScreenMatchSize = (size: Breakpoint) => {
`@672w_378h_1c_!web-search-common-cover`;
//首页up头像大小
`@96w_96h_1s.webp`;

export const useBodyScrollHide = (hidden: boolean) => {
useEffect(() => {
const ScrollSize = getScrollBarSize(),
bodyStyle = document.body.style;
if (hidden) {
bodyStyle.overflow = "hidden";
bodyStyle.paddingRight = `${ScrollSize}px`;
}
return () => {
bodyStyle.overflow = "";
bodyStyle.paddingRight = "";
};
}, [hidden]);
};

0 comments on commit 26f8a26

Please sign in to comment.