2016-09-30 78 views
0

我一直在调整VirtualScroll(列表)组件几乎整天,但没有运气。VirtualScroll(列表)与动态项目高度滚动不平滑和跳跃

我正在构建一个基于Web的聊天应用程序,其中使用react-virtualized List来显示聊天消息。由于消息可能具有不同的内容和不同的高度,因此我使用react-measure来计算项目高度并在rowRenderer中发布重新计算RowHeights

结果很糟糕,每当我停止滚动时,VirtuallScroll List都会跳转。例如,当我滚动到浏览器的一半时,我应该看到消息的中间部分,但它总是突然改变偏移量。请看看录制的视频: https://drive.google.com/file/d/0B_W64UoqloIkcm9oQ08xS09Zc1k/view?usp=sharing

由于我只使用了列表和AUTOSIZER成分,我只能适应所需的css文件到我的项目是一样 ```

.VirtualScroll { 
    width: 100%; 
    outline: none; 
} 

` ``

对于渲染方法,我嵌套很多rowRender内部柔性部件组成: 以下是代码:

```

render() { 
    const inChat = this.context.store.getState().inChat; 
    const {conversationList} = this.state; 
    const imgUrl = 'img/builtin-wallpaper-1.jpg'; 
    const backgroundStyle = { 
     backgroundImage: 'url(' + imgUrl + ')', 
     backgroundRepeat: 'no-repeat', 
     backgroundSize: 'cover', 
     backgroundPosition: 'top left' 
    }; 

    if (inChat.id === this.id && inChat.status === 'FETCHING'){ 
     return (
       <Box column center height="80%"> 
        <CircularProgress /> 
       </Box> 
     ); 
    } else if (inChat.id === this.id && inChat.status === 'FETCHED'){ 
     return (
       <Box column flex="1 0 100%" style={backgroundStyle}> 
        <HorizontalToolBar/> 
        <AutoSizer disableHeight={true}> 
         {({ width }) => (
           <List 
             ref={(element) => {this.VirtualScroll = element;}} 
             className='VirtualScroll' 
             height={window.innerHeight - toolbarHeight - textAreaHeight} 
             overscanRowCount={10} 
             noRowsRenderer={this._noRowsRenderer.bind(this)} 
             rowCount={conversationList.length} 
             rowHeight={i => { 
            return (Measured_Heights[i.index] | 20); // default Height = 58 
           }} 
             rowRenderer={this._rowRenderer} 
             scrollToIndex={undefined} // scroll to latest item 
             width={width} 
           /> 
         )} 
        </AutoSizer> 
        <InputControl chatId={this.id} sendChatText={this._sendChatText.bind(this)}/> 
       </Box> 
     ); 
    } else { 
     return null; 
    } 
} 

_rowRenderer ({ index, key, style, isScrolling }) { 
    console.log(Measured_Heights); 

    const rowData = this._getDatum(index); 
    // let renderItem; 

    // console.log('index = ' + index + ' key = ' + key); 

    if (rowData.type == 'conversation') { 

     if (rowData.data.type == netModule.TYPE_SYSTEM) { 
      // system message 
      return (
        <Measure key={key} onMeasure={(dims) => this._onMeasure(index, dims)}> 
         <SystemMessage data={rowData.data}/> 
        </Measure> 
      ) 
     } 

     if (rowData.data.senderId == this.state.selfProfile.username) { 
      // outgoing message 
      return (
        <Measure key={key} onMeasure={(dims) => this._onMeasure(index, dims)}> 
         <RightMessage 
           screenWidth={(window.innerWidth - leftToolBarWidth)/2 } 
           screenHeight={window.innerHeight - toolbarHeight} 
           data={rowData.data}/> 
        </Measure> 
      ); 

     } else { 
      // incoming message 
      // append userProfile to left messages 
      return (
        <Measure key={key} onMeasure={(dims) => this._onMeasure(index, dims)}> 
         <LeftMessage 
           userId={rowData.data.senderId} 
           userProfile={this.state.groupUserProfiles[rowData.data.senderId]} 
           screenWidth={(window.innerWidth - leftToolBarWidth)/2 } 
           screenHeight={window.innerHeight - toolbarHeight} 
           data={rowData.data}/> 
        </Measure> 
      ); 
     } 
    } 
} 

```

我看过一些文档是Flexbox的可能是拦截滚动事件,但即使我加入溢出-Y:隐藏嵌套组成,我没有看到这个问题消失。你有没有见过这种错误的滚动行为与List组件之前?

任何建议是值得欢迎的。

回答

1

我看不到视频,但我想我最近有类似的东西。从我所看到的,你没有使用传入你的_rowRenderer方法的style参数。此参数包含一些CSS变换,这些变换使行显示在滚动列表的右侧垂直位置。