React Virtualized - как прокрутить до div внутри строки с динамической высотой

Я использую RV List для загрузки большого документа с настраиваемым форматированием. Это сработало как шарм, но я столкнулся со следующими двумя проблемами:
В настоящее время я создаю список в cellmeasurer на основе этого для расчета динамической высоты строк (ширина фиксирована). Мне удалось использовать scrollToindex, чтобы найти нужную строку, но некоторые строки довольно большие, и я хочу иметь возможность прокручивать до определенного места в строке. Я понимаю, что для этого мне нужно использовать scrollTop, но я не знаю, как получить верхнюю часть текущей строки + смещение div внутри строки, чтобы она правильно прокручивалась в нужное положение. Я видел ответ на аналогичный вопрос, где был размещен следующий код:

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?


person akraines    schedule 12.12.2016    source источник


Ответы (1)


Первая половина вашего вопроса немного сложна. Вы можете получить ручку на внутреннем SizeAndPositionManager (используется для управления размерами строк) и запросить у него более точную информацию о смещении. Наименее хакерский способ сделать это - использовать обратный вызов 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)
  }
}

Я предполагаю, что небольшая проблема с перекрытием текста может быть связана с унаследованными стилями. Взято из документации:

Ячейки могут быть измерены вне контекста их предполагаемого Grid (или List). Это означает, что они не будут наследовать родительские стили при измерении. Будьте осторожны, не полагайтесь на унаследованные стили для вещей, которые могут повлиять на измерение (например, размер шрифта). (См. Проблему 352 для получения дополнительной справочной информации.)

Определенные настройки размера блока (например, box-sizing: border-box) могут вызвать небольшие расхождения, если границы применяются к Grid, ячейки которого измеряются. По этой причине рекомендуется избегать размещения границ на Grid, в котором используется CellMeasurer, и вместо этого стилизовать его родительский контейнер. (См. Проблему 338 для получения дополнительной справочной информации.)

person bvaughn    schedule 12.12.2016
comment
Спасибо! Это именно то, что я искал. Однако теперь я столкнулся с проблемой, заключающейся в том, что для использования let target = **document.getElementById(divId)**; let innerOffset = target ? target.offsetTop : 0; dom сначала необходимо отобразить раздел. в противном случае он не найдет div. В настоящее время он работает только в том случае, если div уже находится в прокручиваемой области. Я не могу сделать тайм-аут - person akraines; 14.12.2016
comment
... Я пробовал setTimeout - но это не работает с функцией рендеринга. Есть ли у вас какие-либо предложения, как отложить вторую часть прокрутки до тех пор, пока сектоин не будет отрисован? Спасибо - person akraines; 14.12.2016
comment
следующий SO-ответ реагировать после кода рендеринга Он, наконец, работает точно так, как предполагалось (с использованием 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;})}} - person akraines; 14.12.2016