滚动时,React Virtualized 列表是否可以捕捉到整行?

Is it possible for a React Virtualized list to snap to a full row when scrolling?

我有一个用作下拉菜单的 React Virtualized <List> 组件。我希望列表一次滚动整行,就像普通的 OS 级菜单一样,或者至少在滚动停止时对齐整行。

我已经设置了 scrollToAlignment="top",认为这样可以,但现在我意识到设置 scrollToIndex 时会搞乱滚动行为。

有一个 onScroll 事件,我想我可以设置一个超时,如果在某个 window 内没有收到另一个事件,然后强制 scrollTop显示一整行。但我希望有一种更简洁的方法。

可能的解决方案

与 brianvaughn 的 类似,我使用 onScroll 事件组合了一个解决方案来调用去抖动函数,该函数在短暂延迟后将 scrollTop 捕捉到整行增量:

const RowHeight = 45;

const ResultsList = React.createClass({
    list: null,

    snapRows: _.debounce(function(scrollTop)
    {
        this.list.scrollToPosition(Math.round(scrollTop / RowHeight) * RowHeight);
    }, 100),

    handleRef: function(ref)
    {
        this.list = ref;
    },

    onScroll: function(event)
    {
        this.snapRows(event.scrollTop);
    },

    rowRenderer: function(data)
    { ... },

    render: function()
    {
        var props = this.props;

        return <List
            ref={this.handleRef}
            width={490}
            height={450}
            rowCount={props.items.length}
            rowHeight={RowHeight}
            rowRenderer={this.rowRenderer}
            scrollToIndex={props.selectedIndex}
            onScroll={this.onScroll}
            {...props}
        />
    }
});

但我不是很满意。滚动条末尾的卡扣有点让人分心,如果您仍然按住滚动条拇指,可能会感觉有点奇怪。

我认为让您感觉像是在更新项目列表而不是平滑滚动页面的唯一方法是处理滚动事件并手动定位元素,以便始终将行对齐到偶数行增量。我在 IE5 时代建立了一个类似的虚拟列表,但希望有一个更现代的实现。 :)

这不是我之前实现的用例,所以我没有考虑太多,但你可以使用去抖动的onScrollonSectionRendered 处理程序调用 scrollToCell 并捕捉到特定行。

编辑:这是我所说内容的粗略示例:https://codesandbox.io/s/545y634jxx