简体   繁体   English

JS infine scroll 如何实现

[英]How to implement JS infine scroll

I would like to display a table which have several thousand rows with complex formatting (color, font, border, etc. done on the ASP.Net Core server).我想显示一个包含数千行复杂格式(颜色、字体、边框等在 ASP.Net Core 服务器上完成)的表格。

Initially, I generated an html copy of all the data (stored in a SQL Server database), but realised it wasn't optimal since the generated html data accounted for more than 50MB.最初,我生成了所有数据的 html 副本(存储在 SQL 服务器数据库中),但意识到它不是最佳的,因为生成的 html 数据占了超过 50 个数据。

No, I only generate about 200 rows;不,我只生成大约 200 行; 100 visible and 50 hidden above and below (cache). 100 个可见和 50 个隐藏在上方和下方(缓存)。 I would like to freely scroll the tablen, but when there are only 25 hidden rows above or below, fetch new rows from the controller which are then prepend or append to the table.我想自由滚动表格,但是当上方或下方只有 25 个隐藏行时,从 controller 中获取新行,然后将其添加到表格中或 append 中。 Basically, I want to give enough room so I can can populate the table when I'm scrolling through the "hidden" (cache) rows.基本上,我想留出足够的空间,以便在滚动“隐藏”(缓存)行时可以填充表格。

Everything seems to work well, but I believe I need to use a web-worker to run the function in a background thread which add new rows to the table independently of the table being scrolled.一切似乎都运行良好,但我相信我需要使用网络工作者在后台线程中运行 function,该线程独立于正在滚动的表向表中添加新行。

Below is a excerpt of the code:以下是代码的摘录:

  1. I use a debunce function to only catch the lastest position of the mouse scroll.我使用 debunce function 仅捕获鼠标滚动的最新 position。
  2. The scroll function basically only checks whether there are enough hidden rows (cache) above or below the table.滚动 function 基本上只检查表格上方或下方是否有足够的隐藏行(缓存)。 If it reaches the threshold, it either prepends (scroll upwards) or appends (scroll downwards) rows obtained from the controller.如果达到阈值,它会预先(向上滚动)或附加(向下滚动)从 controller 获得的行。

The main issue is that I can't scroll the table when the new rows are being fetch as the page freezes .主要问题是当页面冻结时获取新行时我无法滚动表格。 It only takes about 1 to 2 seconds to populate to new (scrollable) rows but it isn't smooth.填充到新的(可滚动的)行只需要大约 1 到 2 秒,但并不顺畅。

Could anyone help me improve the code?谁能帮我改进代码? (general ideas) I also read that there are already existing libraries but can't really get my head around them.. (一般想法)我还读到已经存在图书馆,但无法真正理解它们。

$('#fields-table > tbody').on('wheel', _.debounce(async function (event) {
    
    await scroll(); // Probably change it to a web-worker or promise?
}

async function scroll() {
    
    var threshold = 200; // Corresponds to approximatively 50 rows (above and below).

    var above = $('#fields-table').scrollTop();
    var below = $('#fields-table > tbody').height() - $('#fields-table').height() - above;

    // Gets the scroll delta based on the table heights.
    var delta = 0
            
    if (above < threshold) delta = above - threshold; // Scrolls upwards.

    if (below < threshold) delta = threshold - below; // Scrolls downwards.
    
    await addCacheRows(delta); // Prepends (delta < 0) or appends (delta > 0) or appends rows obtained via the fetch API.
}

Your problem is unlikely to resolve with a web worker. web 工作人员不太可能解决您的问题。 Without seeing more code I cannot tell for sure, but I suspect your code to generate new rows is not sufficiently efficient.如果没有看到更多代码,我无法确定,但我怀疑您生成新行的代码效率不够高。 Remember:记住:

  • Use DocumentFragment to create the HTML, do not immediately append it to the main DOM tree row by row.使用DocumentFragment创建 HTML,不要立即将 append 逐行添加到主 DOM 树中。 Appending elements to a document triggers some recalculations.将元素附加到文档会触发一些重新计算。
  • Unless this is a LOT of data or requires lots of work serverside, you can immediately start preloading next/previous rows.除非这是大量数据或需要大量工作服务器端,否则您可以立即开始预加载下一行/上一行。 Keep the promise object and only await it once you need them, that's the simplest way to go around it保留 promise object 并仅在需要时await它,这是 go 围绕它的最简单方法
  • Use passive scroll event listener - Firefox even shows a console warning whenever you do not do that使用被动滚动事件侦听器 - Firefox 甚至在您不这样做时显示控制台警告

There is no way generating 200 rows of table data should take seconds.没有办法生成 200 行表数据需要几秒钟。 Since you use JQuery anyway (really, in 2022?), note that there are plugins for this.由于您无论如何都使用 JQuery (真的,在 2022 年?),请注意有用于此的插件。 I don't remember what I used, but it worked perfect and scrolled smooth with much more data than what you have.我不记得我用了什么,但它运行完美,滚动流畅,数据比你拥有的多得多。

Thank you for your help.谢谢您的帮助。 I realise it won't be as straightforward as I initally thought (I made some tests with WPF virtualization as well).我意识到它不会像我最初想象的那么简单(我也用 WPF 虚拟化做了一些测试)。

Regarding the time it takes to generate the extra rows, I believe it mostly comes from the server.关于生成额外行所需的时间,我相信它主要来自服务器。 Sure, I can probably load new rows independently of the threshold.当然,我可能可以独立于阈值加载新行。

I've never heard about DocumentFragment , but that something I should definitely consider.我从未听说过DocumentFragment ,但我绝对应该考虑这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM