React Virtualized - 如何滚动到具有动态高度的行内的 div
Posted
技术标签:
【中文标题】React Virtualized - 如何滚动到具有动态高度的行内的 div【英文标题】:React Virtualized - how to scroll to div within row with dynamic height 【发布时间】:2017-04-27 20:03:08 【问题描述】:我正在使用 RV List 加载具有自定义格式的大型文档。它就像一个魅力,但我遇到了以下两个问题: 我目前在 cellmeasurer based on this 中设置了一个列表来计算行的动态高度(宽度是固定的)。我设法使用 scrollToindex 找到我想要的行,但有些行非常大,我希望能够滚动到行中的特定位置。我知道我需要使用 scrollTop 来执行此操作,但我不知道如何获取当前行的顶部 + 行内 div 的偏移量以使其正确滚动到正确的位置。 我看到an answer to a similar question 贴出了以下代码:
function render ( scrollToIndex, ...rest )
// Convert scrollToIndex to scrollStop
const scrollTop =
**rowOffset** + // Position of row within List
**innerOffset** // Position of inner target within row
这是我的代码:
<AutoSizer>
( width, height ) => (
<CellMeasurer
cellRenderer=(index, isScrolling, style, key ) => SectionRenderer(index, key, style)
columnCount=1
rowCount=getSectionCount
width=width
>
( getRowHeight ) => (
<List
height=height
rowHeight=getRowHeight
rowCount=getSectionCount
rowRenderer=( index, isScrolling, style, key ) => SectionRenderer(index, key, style)
overscanRowCount=10
width=width
scrollToIndex=scrollToSectionIndex
/>
)
</CellMeasurer>
)
</AutoSizer>
我遇到的另一个问题是,虽然我将文档分成多个块,每个块都以一个标签结尾,以确保文本的流畅(不重叠),但由于某种原因,文本中有一些点单元格测量器忽略导致重叠的行 div 的最后一行文本的高度。我还没有设法找到关于列表中重叠发生位置的一致模式。你有什么指示我如何调试这个问题:例如。单独测量给定部分并将其与 CellMeasurer 返回的测量值进行比较?
【问题讨论】:
【参考方案1】:你问题的前半部分有点棘手。您可以在内部 SizeAndPositionManager
(用于管理行大小)上获得一个 hanlde 并查询它以获取更准确的偏移信息。最简单的做法是使用cellRangeRenderer
回调,大致如下:
import defaultCellRangeRenderer, Grid from 'react-virtualized'
class GridWrapperExample extends Component
constructor (props, context)
super(props, context)
this._cellRangeRenderer = this._cellRangeRenderer.bind(this)
render ()
return (
<Grid
cellRangeRenderer=this._cellRangeRenderer
...this.props
/>
)
_cellRangeRenderer (props)
this._rowSizeAndPositionManager = props.rowSizeAndPositionManager
return defaultCellRangeRenderer(props)
我的猜测关于轻微的文本重叠问题是它可能与继承的样式有关。取自the docs:
可以在预期的
Grid
(或List
)的上下文之外测量单元格。这意味着它们在测量时不会继承父样式。注意不要依赖继承的样式来影响测量(例如字体大小)。 (有关更多背景信息,请参阅第 352 期。)如果将边框应用于正在测量其单元格的
Grid
,某些框大小设置(例如box-sizing: border-box
)可能会导致细微差异。因此,建议您避免在使用CellMeasurer
的Grid
上放置边框,而是设置其父容器的样式。 (有关更多背景信息,请参阅第 338 期。)
【讨论】:
谢谢!这正是我一直在寻找的。但是我现在遇到了一个问题,为了使用let target = **document.getElementById(divId)**; let innerOffset = target ? target.offsetTop : 0;
,dom 首先需要渲染该部分。否则它不会找到 div。它目前仅在 div 已经在可滚动区域内时才有效。我不能超时
... 我尝试了 setTimeout - 但这在渲染函数中不起作用。您对如何将卷轴的第二部分延迟到渲染 sectoin 有什么建议吗?谢谢
遵循 SO answer react after render code 它最终完全按预期工作(使用 mobx):@observable delayedScrollTo = 0; onNextFrame(cb)... componentDidUpdate(prevProps, prevState) if (this.props.scrollToDivId != prevProps.scrollToDivId) let rowInfo = this._rowSizeAndPositionManager.getSizeAndPositionOfCell(this.props.scrollToIndex); this.onNextFrame(() => let target = document.getElementById(this.props.scrollToDivId); let innerOffset = target ? target.offsetTop : 0; this.delayedScrollTo = innerOffset;)
以上是关于React Virtualized - 如何滚动到具有动态高度的行内的 div的主要内容,如果未能解决你的问题,请参考以下文章
在我滚动之前,react-virtualized 列表项不会使用更改的道具重新渲染
有没有办法通过 react-virtualized 将 ref 设置为 List ?