Javascript 反应滚动事件不';不要停止射击

Javascript 反应滚动事件不';不要停止射击,javascript,reactjs,dom,react-hooks,dom-events,Javascript,Reactjs,Dom,React Hooks,Dom Events,在工作中,我们在呈现数据表时遇到一些性能问题,因此我们决定尝试虚拟化列表“窗口”。基本上遵循与的相同思想,即只渲染数据列表的子列表(显示在视口中的子列表) 出于种种原因,我们试图自己实现这项技术。通过这样做,我们了解到这主要是通过对每个列表项使用position:absolute来完成的,这并不真正适合我们。因此,我们想出了一个主意,就是在要渲染的子列表周围有两个“包装器”div。 基本上,box1的高度等于窗口前所有列表项的合并高度,box2的高度等于窗口后所有列表项的高度。每次用户滚动时,我

在工作中,我们在呈现数据表时遇到一些性能问题,因此我们决定尝试虚拟化列表“窗口”。基本上遵循与的相同思想,即只渲染数据列表的子列表(显示在视口中的子列表)

出于种种原因,我们试图自己实现这项技术。通过这样做,我们了解到这主要是通过对每个列表项使用
position:absolute
来完成的,这并不真正适合我们。因此,我们想出了一个主意,就是在要渲染的子列表周围有两个“包装器”div。 基本上,box1的高度等于窗口前所有列表项的合并高度,box2的高度等于窗口后所有列表项的高度。每次用户滚动时,我们都会找出要渲染的索引并调整框的高度

不幸的是,我们遇到了这样一个问题:当用户向下滚动时,即使在用户停止滚动之后,滚动事件仍会持续触发。这会将列表一直滚动到最后。不过,当向上滚动时,它似乎工作正常,所以我们在这里真的很茫然。我们不明白它为什么一直开火

。为了简单起见,我用一个固定的框替换了所有列表项逻辑。我还为scroll处理程序添加了一个超时,因此向上滚动的行为更明显,否则它太快,红色的上框不明显

非常感谢您的帮助。提前谢谢


编辑:我们实际上是在
元素中使用它,这意味着基于css
position
属性的解决方案将不起作用,因为该属性对表元素具有未定义的行为,并且它打破了标准的表格布局。

问题最有可能是由于使用scrollTop值来更改导致scrollTop值更改的项目的高度,等等(可能)

这是正确的方法

import React,{useState,useCallback}来自“React”;
从“react dom”导入react dom;
const ROW_HEIGHT=25;
常量应用=(道具)=>{
const[items,innerHeight,onScroll]=useVirtualizedList({
单位:500,
itemHeight:行高,
窗高:行高*5,
窗口扩展名:0
});
返回(
{items}
);
};
const useVirtualizedList=({numItems,itemHeight,windowHeight})=>{
常量[scrollTop,setScrollTop]=useState(0);
const innerHeight=numItems*itemHeight;
const startIndex=数学楼层(滚动顶部/项目高度);
const endIndex=Math.min(
numItems-1,
startIndex+数学楼层(窗高/项目高度)
);
const onScroll=useCallback((e)=>{
const currentScroll=e.currentTarget.scrollTop;
setScrollTop(当前滚动);
}, []);
常量项=`${startIndex}--${endIndex}`
返回[项目、内部高度、onScroll];
};
render(,document.getElementById(“根”));

react window为什么不适合您?您还尝试过
react virtualized
list吗?主要原因是两个lib都依赖于
position:absolute
,后者对html元素具有未定义的行为。它们还强制您使用自己的组件,这些组件添加了与我们的层次结构和样式指南冲突的额外html。它进一步依赖于儿童模式的功能,我们认为这是一个坏的模式,尽管我们可以在这方面工作。这是react-libs的一个常见问题,在react-libs中,行为是通过组件/html公开的,而不是视图无关的。React table就是我在libs中寻找的一个例子。@tiansive用HTML和CSS制作一个滚动条会更好,我想,这样你就不需要设置位置。问题是你依赖于使用CSS
position
,这对我们不起作用,因为这必须应用于元素。根据规范,定位似乎对表元素具有未定义的行为,并不断破坏表布局。也许我应该在问题中更清楚地说明这一点。我会编辑它。因此,如果一个子对象被调整大小,scroll top属性将发生更改,如果总高度保持不变,则会发生事件?这对我来说没有多大意义,我想定制的滚动条可能是一个很好的解决办法,我没有想到这一点@tiansivive您可以制作一个宽度等于滚动条宽度的div来赢得一些时间
import React, { useState, useCallback } from "react";
import ReactDOM from "react-dom";

const ROW_HEIGHT = 25;

const App = (props) => {
  const [items, innerHeight, onScroll] = useVirtualizedList({
    numItems: 500,
    itemHeight: ROW_HEIGHT,
    windowHeight: ROW_HEIGHT * 5,
    windowExtension: 0
  });
  return (
    <div onScroll={onScroll} style={{ height: "500px", overflowY: "scroll" }}>
      <div style={{
        // position should be calculated depanding on the parent element position
        position: 'fixed'
      }}>{items}</div>
      <div className="forceOverflow" style={{height: 500 * ROW_HEIGHT}}></div>
    </div>
  );
};


const useVirtualizedList = ({ numItems, itemHeight, windowHeight }) => {
  const [scrollTop, setScrollTop] = useState(0);

  const innerHeight = numItems * itemHeight;
  const startIndex = Math.floor(scrollTop / itemHeight);
  const endIndex = Math.min(
    numItems - 1,
    startIndex + Math.floor( windowHeight / itemHeight)
  );

  const onScroll = useCallback((e) => {
    const currentScroll = e.currentTarget.scrollTop;
    setScrollTop(currentScroll);
  }, []);

  const items = `${startIndex} --- ${endIndex}`

  return [items, innerHeight, onScroll];
};

ReactDOM.render(<App />, document.getElementById("root"));