【问题标题】:React Virtualized - how to scroll to div within row with dynamic heightReact Virtualized - 如何滚动到具有动态高度的行内的 div
【发布时间】: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 返回的测量值进行比较?

【问题讨论】:

    标签: react-virtualized


    【解决方案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)可能会导致细微差异。因此,建议您避免在使用 CellMeasurerGrid 上放置边框,而是设置其父容器的样式。 (有关更多背景信息,请参阅第 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(() =&gt; {let target = document.getElementById(this.props.scrollToDivId); let innerOffset = target ? target.offsetTop : 0; this.delayedScrollTo = innerOffset;})}}
    猜你喜欢
    • 2013-01-05
    • 2017-04-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-22
    • 1970-01-01
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    相关资源
    最近更新 更多