Javascript 对于动态高度列表,scrollToRow结果处于关闭状态

Javascript 对于动态高度列表,scrollToRow结果处于关闭状态,javascript,reactjs,pdf,react-virtualized,Javascript,Reactjs,Pdf,React Virtualized,首先,让我提供一些关于react虚拟化用例的背景信息。我将它与的v2.0 beta版结合使用,以构建一个pdf查看器,该查看器可以更高效地显示/呈现具有大量页面的pdf文档。一个重要的要求是pdf查看器具有完全的响应能力,能够处理页面高度可能不同的文档 我已经成功地将这两个包结合在一起(有几个与pdf相关的小问题),但是有一些事情并不像我预期的那样有效。最值得注意的是,滚动到特定行(即页面)的效果并不太好。举个例子,如果我试图从页面索引0滚动到页面索引81(大约是我的152页测试pdf的中间部分

首先,让我提供一些关于react虚拟化用例的背景信息。我将它与的v2.0 beta版结合使用,以构建一个pdf查看器,该查看器可以更高效地显示/呈现具有大量页面的pdf文档。一个重要的要求是pdf查看器具有完全的响应能力,能够处理页面高度可能不同的文档

我已经成功地将这两个包结合在一起(有几个与pdf相关的小问题),但是有一些事情并不像我预期的那样有效。最值得注意的是,滚动到特定行(即页面)的效果并不太好。举个例子,如果我试图从页面索引0滚动到页面索引81(大约是我的152页测试pdf的中间部分),我会在所需页面和下一页之间的某个中间位置结束。如果我试图滚动到最后一页索引(p.I.151),我会在最后一页的下一页结束

我使用了
WindowScroller
AutoSizer
CellMeasurer
List
的组合来创建我的查看器(我省略了一些不直接重要的部分):

类查看器扩展组件{
建造师(道具){
超级(道具);
this.state={pdf:null,比例:1.2};
这个._cache=newCellMeasureCache({defaultHeight:768,fixedWidth:true});
}
...
handleResize(){
此。_cache.clearAll();//重置所有单元格的缓存测量值
}
updatePageIndex(索引){
这个;
此._list.scrollToRow(索引);
}
行渲染器({key,index,style,parent}){
返回(
{
({measure})=>(
)
}
);
}
render(){
...
{
({高度,isScrolling,onChildScroll,scrollTop})=>(
{
({width})=>(
这个。_list=ref}/>
)
}
)
}
}
}
...

我在
updatePageIndex()
中所做的是正确的还是仍然缺少什么?

我认为上面有一两个误解。首先,调用
cache.clearAll()
将删除所有测量值-需要
CellMeasurer
在下一次渲染时重新计算所有测量值。除非某些改变使这些测量无效(从您的描述来看,情况似乎并非如此),否则您不会希望这样做。只有当测量值可能因浏览器宽度调整等更改而无效时,才应调用此方法,这可能会影响包装文本内容的高度等

其次,如果您确实需要调用
cache.clearAll()
,那么您还需要调用
list.recomputeroweights()
<代码>CellMeasurer缓存测量值(大小)和
列表
缓存位置(偏移)。这使得数据可以重新排序(如排序),而无需重新测量。排序后所需的一切就是让
List
重新计算其位置

查看使用react virtualized构建的I Build,了解如何实现这一点的示例


如果上述信息不能帮助您解决问题,请在CodeSandbox或类似网站上留下评论和评论,我会看一看。

我认为上面有一两个误解。首先,调用
cache.clearAll()
将删除所有测量值-需要
CellMeasurer
在下一次渲染时重新计算所有测量值。除非某些改变使这些测量无效(从您的描述来看,情况似乎并非如此),否则您不会希望这样做。只有当测量值可能因浏览器宽度调整等更改而无效时,才应调用此方法,这可能会影响包装文本内容的高度等

其次,如果您确实需要调用
cache.clearAll()
,那么您还需要调用
list.recomputeroweights()
<代码>CellMeasurer缓存测量值(大小)和
列表
缓存位置(偏移)。这使得数据可以重新排序(如排序),而无需重新测量。排序后所需的一切就是让
List
重新计算其位置

查看使用react virtualized构建的I Build,了解如何实现这一点的示例


如果上面的信息不能帮助您解决问题,请在CodeSandbox或类似网站上留下评论和重做,我会看一看。

我让它正常工作的唯一方法(即滚动到右侧页面)是使用
列表
组件的
scrollToIndex
属性。奇怪的是,将其设置为某一行索引确实会滚动到右侧页面


使用
scrollToIndex
的唯一问题是,它不允许您通过滚动索引向上滚动。我的解决方法是在滚动完成后将索引设置回-1。但是,如果我做得太快,
scrollToIndex
也会滚动到错误的行。我解决这个问题的唯一方法是使用
setTimeout()
将索引设置为-1。非常黑,但它确实有用。我尝试了使用
componentdiddupdate()
和一个承诺的其他方法,但没有一种方法对我有效。

我让它正常工作的唯一方法(即滚动到右侧页面)是使用
列表
组件的
scrollToIndex
属性。奇怪的是,将其设置为某一行索引确实会滚动到右侧页面

使用scrollToIndex的唯一问题是它不允许您使用sc
class Viewer extends Component {
    constructor(props) {
        super(props);

        this.state = {pdf: null, scale: 1.2};
        this._cache = new CellMeasurerCache({defaultHeight: 768, fixedWidth: true});
    }

    ...

    handleResize() {
        this._cache.clearAll();     // Reset the cached measurements for all cells
    }

    updatePageIndex(index) {
        this._cache.clearAll();
        this._list.scrollToRow(index);
    }

    rowRenderer({key, index, style, parent}) {
        return (
            <CellMeasurer cache={this._cache} columnIndex={0} key={key} parent={parent} rowIndex={index}>
                {
                    ({measure}) => (
                        <div style={style}>
                            <Page
                                onLoadSuccess={measure}
                                renderTextLayer={false}
                                pdf={this.state.pdf}
                                pageNumber={index + 1}
                                scale={this.state.scale} />
                        </div>
                    )
                }
            </CellMeasurer>
        );
    }

    render() {
        ...
        <Document
            file="./some_pdf_document.pdf"
            loading={<Loader />}
            error={this.renderError()}
            onLoadSuccess={this.onDocumentLoadSuccess.bind(this)}
        >
            <WindowScroller onResize={this.handleResize.bind(this)}>
                {
                    ({height, isScrolling, onChildScroll, scrollTop}) => (
                        <AutoSizer disableHeight>
                            {
                                ({width}) => (
                                    <List
                                        autoheight
                                        height={height}
                                        width={width}
                                        isScrolling={isScrolling}
                                        onScroll={onChildScroll}
                                        scrollToAlignment="start"
                                        scrollTop={scrollTop}
                                        overscanRowCount={5}
                                        rowCount={this.state.pdf.numPages}
                                        deferredMeasurementCache={this._cache}
                                        rowHeight={this._cache.rowHeight}
                                        rowRenderer={this.rowRenderer.bind(this)}
                                        style={{outline: 'none'}}
                                        ref={ref => this._list = ref} />
                                )
                            }
                        </AutoSizer>
                    )
                }
            </WindowScroller>
        </Document>
    }

}
...