如何在佈局中始終平均分配剩餘空間給間隙(gap)
不廢話,直接上程式碼:
import { useEffect } from "react";
import "./styles.css";
export default function App() {
function dynamicCalculate() {
const container = document.getElementById("container") as HTMLElement;
const item = container.firstElementChild as HTMLElement;
let W: number; // Width of container.
let w: number; // Width of item.
let b: number; // Border's width of item.
let minGap: number; // Minimum gap between items.
let gap: number; // Gap between items.
let n: number; // Number of items in one row.
W = container.clientWidth;
w = item.clientWidth;
b = +window.getComputedStyle(item).borderWidth.replace("px", "") * 2;
w = w + b;
minGap = 16;
n = Math.floor(W / w);
function calc(n: number): [number, number] {
gap = (W - n * w) / (n + 1);
if (gap < minGap) {
n--;
gap = (W - n * w) / (n + 1);
return calc(n);
}
return [n, gap];
}
[n, gap] = calc(n);
console.log(`Put ${n} items in one row, gap is ${gap}px.`);
const halfGap = gap / 2;
container.style.paddingLeft = `${halfGap}px`;
container.style.paddingRight = `${halfGap}px`;
for (let item of container.children) {
(item as HTMLElement).style.marginLeft = `${halfGap}px`;
(item as HTMLElement).style.marginRight = `${halfGap}px`;
}
}
useEffect(() => {
dynamicCalculate();
window.addEventListener("resize", dynamicCalculate);
return () => {
window.removeEventListener("resize", dynamicCalculate);
};
}, []);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
{/* demo */}
<div
id="container"
className="flex-h wrap"
style={{
display: "flex",
flexFlow: "row wrap",
border: "1px solid red"
}}
>
{Array.from({ length: 20 }).map((v, i) => {
return (
<div
className="flex-h center"
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
border: "1px solid blue",
width: "100px",
height: "120px"
}}
>
Item-{i}
</div>
);
})}
</div>
</div>
);
}
codesandbox地址:demo線上預覽