提问人:Vlad Em 提问时间:5/22/2023 更新时间:5/22/2023 访问量:135
如何使用 react-wondow 和 display:sticky 将一列贴在表格的右边?
How to stick a column to the right in a table using react-wondow and display:sticky?
问:
我目前正在创建一个包含大量数据的复杂表。 正因为如此,我决定选择虚拟化(react-window)。 一切都会好起来的,但我需要冻结表中的第一行、左列和右列。 我找到了一个很好的例子: https://codesandbox.io/s/strange-feistel-kwsed?file=/index.js 但是表格中只有第一行和左列是固定的。还需要修复右侧的最后一列。 我遇到了这个问题,想请你帮忙。
索引.js
import React from "react";
import ReactDOM from "react-dom";
import { GridWithStickyCells } from "./grid-with-sticky-cells";
import "./styles.css";
// These cell sizes are arbitrary.
// Yours should be based on the content of the cell.
const columnWidths = new Array(1000)
.fill(true)
.map(() => 75 + Math.round(Math.random() * 50));
const rowHeights = new Array(1000)
.fill(true)
.map(() => 25 + Math.round(Math.random() * 50));
const Cell = ({ columnIndex, rowIndex, style }) => (
<div
className={
columnIndex % 2
? rowIndex % 2 === 0
? "GridItemOdd"
: "GridItemEven"
: rowIndex % 2
? "GridItemOdd"
: "GridItemEven"
}
style={style}
>
r{rowIndex}, c{columnIndex}
</div>
);
const Example = () => (
<GridWithStickyCells
className="Grid"
columnCount={1000}
columnWidth={(index) => columnWidths[index]}
height={600}
rowCount={1000}
rowHeight={(index) => rowHeights[index]}
width={600}
>
{Cell}
</GridWithStickyCells>
);
ReactDOM.render(<Example />, document.getElementById("root"));
网格与粘性单元格.jsx
import React from "react";
import { VariableSizeGrid as Grid } from "react-window";
function getCellIndicies(child) {
return { row: child.props.rowIndex, column: child.props.columnIndex };
}
function getShownIndicies(children) {
let minRow = Infinity;
let maxRow = -Infinity;
let minColumn = Infinity;
let maxColumn = -Infinity;
React.Children.forEach(children, (child) => {
const { row, column } = getCellIndicies(child);
minRow = Math.min(minRow, row);
maxRow = Math.max(maxRow, row);
minColumn = Math.min(minColumn, column);
maxColumn = Math.max(maxColumn, column);
});
return {
from: {
row: minRow,
column: minColumn
},
to: {
row: maxRow,
column: maxColumn
}
};
}
function useInnerElementType(Cell, columnWidth, rowHeight) {
return React.useMemo(
() =>
React.forwardRef((props, ref) => {
function sumRowsHeights(index) {
let sum = 0;
while (index > 1) {
sum += rowHeight(index - 1);
index -= 1;
}
return sum;
}
function sumColumnWidths(index) {
let sum = 0;
while (index > 1) {
sum += columnWidth(index - 1);
index -= 1;
}
return sum;
}
const shownIndecies = getShownIndicies(props.children);
const children = React.Children.map(props.children, (child) => {
const { column, row } = getCellIndicies(child);
// do not show non-sticky cell
if (column === 0 || row === 0) {
return null;
}
return child;
});
children.push(
React.createElement(Cell, {
key: "0:0",
rowIndex: 0,
columnIndex: 0,
style: {
display: "inline-flex",
width: columnWidth(0),
height: rowHeight(0),
position: "sticky",
top: 0,
left: 0,
zIndex: 4
}
})
);
const shownColumnsCount =
shownIndecies.to.column - shownIndecies.from.column;
for (let i = 1; i <= shownColumnsCount; i += 1) {
const columnIndex = i + shownIndecies.from.column;
const rowIndex = 0;
const width = columnWidth(columnIndex);
const height = rowHeight(rowIndex);
const marginLeft = i === 1 ? sumColumnWidths(columnIndex) : undefined;
children.push(
React.createElement(Cell, {
key: `${rowIndex}:${columnIndex}`,
rowIndex,
columnIndex,
style: {
marginLeft,
display: "inline-flex",
width,
height,
position: "sticky",
top: 0,
zIndex: 3
}
})
);
}
const shownRowsCount = shownIndecies.to.row - shownIndecies.from.row;
for (let i = 1; i <= shownRowsCount; i += 1) {
const columnIndex = 0;
const rowIndex = i + shownIndecies.from.row;
const width = columnWidth(columnIndex);
const height = rowHeight(rowIndex);
const marginTop = i === 1 ? sumRowsHeights(rowIndex) : undefined;
children.push(
React.createElement(Cell, {
key: `${rowIndex}:${columnIndex}`,
rowIndex,
columnIndex,
style: {
marginTop,
width,
height,
position: "sticky",
left: 0,
zIndex: 2
}
})
);
}
return (
<div ref={ref} {...props}>
{children}
</div>
);
}),
[Cell, columnWidth, rowHeight]
);
}
export function GridWithStickyCells(props) {
return (
<Grid
{...props}
innerElementType={useInnerElementType(
props.children,
props.columnWidth,
props.rowHeight
)}
/>
);
}
我试图改变代码的样子,但它没有使最后一列粘在右边缘。我花了一天半的时间,但无法解决问题。 我很乐意提供任何帮助。先谢谢你!
答: 暂无答案
评论