gpt4 book ai didi

javascript - 如何在窗口调整大小时更新 useRef Hook 的值

转载 作者:行者123 更新时间:2023-11-28 03:23:23 25 4
gpt4 key购买 nike

我有一个表格组件,在水平滚动时具有固定的第一列。我通过绝对定位来做到这一点。这会导致一个问题。

调整窗口大小时,表格单元格的内容可能会换行并导致单元格的高度也随之调整。我已经为表格组件设置了一个引用,以便我可以通过 JavaScript 获取行高并相应地调整绝对定位的固定单元格的大小。

代码如下:

  const NewStatsTable = ({ headers, stats, data, dataType }) => {
const [cellHeights, setCellHeights] = useState([])
const tableRef = useRef(null)

useLayoutEffect(() => {
handleCellHeightResize()
window.addEventListener('resize', handleCellHeightResize)
return window.removeEventListener('resize', handleCellHeightResize)
}, [])

const headersToUse = getHeaders(dataType)

const getData = (item, header) => {
if (header === 'gameDate') return formatDate(item[headersToUse[header].id])
return item[headersToUse[header].id]
}

const getTallestCellHeights = () => {
const rows = Array.from(tableRef.current.getElementsByTagName('tr'))

return rows.map(row => {
const fixedCell = row.childNodes[0]
return Math.max(row.clientHeight, fixedCell.clientHeight)
})
}

const handleCellHeightResize = () => {
setCellHeights(getTallestCellHeights)
}

const headerMarkup = () => (
<TableRow header>{headers.map(renderHeaderRow)}</TableRow>
)

const renderHeaderRow = (header, colIndex) => {
const text = headersToUse[header].headerText
const height = cellHeights[0]

return (
<TCell
key={header}
type='th'
data={text}
colIndex={colIndex}
cellHeight={height}
/>
)
}

const cellMarkup = () =>
data.map((row, rowIndex) => (
<TableRow key={row._id}>
{headers.map((header, colIndex) =>
renderRow(header, row, rowIndex, colIndex)
)}
</TableRow>
))

const renderRow = (header, row, rowIndex, colIndex) => {
const text = getData(row, header)
const height = cellHeights[rowIndex + 1]

return (
<TCell
key={header}
type='td'
data={text}
colIndex={colIndex}
cellHeight={height}
/>
)
}

return (
<Container>
<ScrollContainer>
<Table ref={tableRef}>
<TableHead>{headerMarkup()}</TableHead>
<TableBody>{cellMarkup()}</TableBody>
</Table>
</ScrollContainer>
</Container>
)
}

该代码可以工作,但在调整大小时不起作用,仅在首次加载页面时才起作用。如果窗口足够窄,则可以正确计算较高的像元高度。当然,当窗口很宽并且单元格中没有文本换行时,情况也是如此。

当我调整窗口大小时,行高不会重新计算。我想这是因为 tableRef 是在页面加载时创建的,即使调整页面大小也不会创建。

我尝试为 resize 事件添加事件监听器,但没有帮助。 getTallestCellHeights 仍然使用旧的 ref 进行计算。

如何更新 tableRef 以便 getTallestCellHeights 使用正确的高度进行计算?

最佳答案

我认为这里的问题是高度的计算。您使用的clientHeight不包括边距。随着页面大小的调整,计算出的高度正在变化,并且可能有一些媒体查询更新边距。

useRef 可能按预期工作,但您的计算并未考虑元素高度的所有值。

考虑下面代码片段中的函数:

  function calcHeight(el) {
const styles = window.getComputedStyle(el);
const margin =
parseFloat(styles["marginTop"]) + parseFloat(styles["marginBottom"]);

console.log(`trueHeight: ${Math.ceil(el.offsetHeight + margin)}`, `clientHeight: ${el.clientHeight}`);

return Math.ceil(el.offsetHeight + margin);
}

您会看到实际高度有所不同。

function calcHeight(el) {
const styles = window.getComputedStyle(el);
const margin = parseFloat(styles["marginTop"]) + parseFloat(styles["marginBottom"]);

console.log(`trueHeight: ${Math.ceil(el.offsetHeight + margin)}`, `clientHeight: ${el.clientHeight}`);

return Math.ceil(el.offsetHeight + margin);
}

const demo = document.querySelector('.demo');

function onResize(e) {
calcHeight(demo);
}

window.addEventListener("resize", onResize);

onResize(demo);
.container {
display: flex;
justify-content: center;
align-items: center;
background: black;
width: 100vw;
height: 100vh;
}

.demo {
background: red;
padding: 25px;
margin: 25px;
border: 1px solid #fff;
}

@media (min-width: 500px) {
.demo {
margin: 50px;
background: green;
}
}
<div class="container">
<div class="demo">
<h1>Some Content</h1>
</div>
</div>

Basic React Demo on codeandsandbox

关于javascript - 如何在窗口调整大小时更新 useRef Hook 的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58903786/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com