【问题标题】:Get all elements in viewport Javascript获取视口Javascript中的所有元素
【发布时间】:2020-02-10 19:07:35
【问题描述】:

我想知道是否有可能(在 javascript 或 jquery 中,但没有任何插件)在当前视口中获取所有元素(例如表行 tr)而不遍历每个元素?我找到了很多示例如何检查指定元素是否在当前视口中,但我需要的是一个函数返回当前视口中所有元素的列表。我需要这个来进行虚拟化,因为这个表应该有无限的容量,并且从两百万行中循环遍历每一行是非常低效的 :)

有什么合理的方法可以做到这一点吗?

【问题讨论】:

  • 对于诸如表格之类的东西,您可以进行二进制搜索来找到它,假设您不关心或不使用位于其父级之外或重叠的任何元素。
  • 不,除非您循环遍历元素以检查它们是否在屏幕外,否则这是不可能的。
  • 您可以通过计算窗口的当前滚动位置来缩小循环范围,如下所示:stackoverflow.com/questions/3658496/…

标签: javascript algorithm binary-search


【解决方案1】:

假设您没有在定位方面做任何花哨的事情,可以通过二分搜索找到视口中的表行。例如,对于 200000 行,大约需要 18 次查找才能找到页面上的第一行(jsfiddle,警告:加载缓慢)。这也可以扩展为查找最后一个元素,或者您可以从第一个元素开始循环遍历元素,直到找到不再可见的元素。

var rows = table.children().children();
var start = 0;
var end = rows.length;
var count = 0;

while(start != end) {
    var mid = start + Math.floor((end - start) / 2);
    if($(rows[mid]).offset().top < document.documentElement.scrollTop)
        start = mid + 1;
    else
        end = mid;
}

显然,如果任何东西是浮动的、绝对定位的等,这将无法正常工作。简而言之:被搜索的节点必须按照rows[N-1].top &lt;= rows[N].top 的顺序排列。对于诸如表格之类的东西,如果没有应用样式并且不存在多行单元格,这应该是正确的。

【讨论】:

  • 我真的不明白这个jsfiddle代码在做什么......它搜索我假设的视口中可见的第一行?那为什么还提示第一行是R0呢?我猜这应该取决于视口位置。
  • @AdamMrozek:可能你的浏览器不支持document.documentElement.scrollTop。它在 Firefox 中运行良好。我已经更新了小提琴以使用 jQuery 的scrollTop,这可能会更好。
  • 好的,现在我有另一个相关的问题:是否可以计算包含不同高度行的表格的滚动高度?也许我应该问另一个问题而不是评论?
  • 并非没有枚举每一行。唯一的例外是行的高度不同,但这只是因为您只有几种不同类型的固定高度(例如一种是 100 像素,另一种是 150 像素)。然后你可以计算不同的类型,而不是查询每个 DOM 元素的高度。
猜你喜欢
  • 2020-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多