2011-12-28 165 views
1

我在HTML中有一个可更新的频繁表(每秒大约一次),可以包含1000行以上的内容。显然,每次更新时都替换整个表是不合理的,所以我想只替换当前可见的表格行。获取滚动到视图中的所有HTML元素

我的第一次尝试是检查遍历所有行并检查它们的偏移量;这有效,但它太慢而不能有效。

我试图现在要做的就是用document.elementFromPoint()找到上层建筑的<tbody>最顶端的元素,通常是从哪里可以得到它含有<tr>一个<td>元素。除了表格本身被另一个元素遮挡的情况(例如浮动的灯箱),这几乎可以工作。

我目前正在寻找第三种解决方案,或者在特定点下获取所有元素的方法,而不仅仅是最上面的一个。如果任何人有任何想法如何实现这些,那将非常感激。

+0

为什么不分页行? – 2011-12-28 21:59:00

+0

我想到了这一点,但用户不得不交换页面而不是仅仅滚动 - 这与无限滚动技术流行的原因相同。 – sslepian 2011-12-28 22:00:53

+0

我不知道你是否在使用/愿意使用jQuery,但如果我没有误解,[这个插件](http://www.appelsiini.net/projects/viewport)似乎符合你的需求。 – pimvdb 2011-12-28 22:02:32

回答

0

所以我在想这个,想出了这个。

http://jsfiddle.net/RKzRE/7/

不能监视所有1000行只是监视它们的子集。在页面加载时缓存他们的滚动页面以提高效率。那么如果更新显示区域上方或下方的几行呢?您可以在粒度和更新速度之间找到快乐的媒介。

我只实现了向下滚动和硬编码要更新的行数。但我认为细节很容易弄清楚。

//create an object to hold a list of row top locations 
var rowmarkers = new Object; 

//gather all rows and store their top location 
$('tr').each(function(index) { 
    //create markers for every ten rows 
    if (index % 10 == 0) { 
     $(this).addClass('marker'); 
     rowmarkers[$(this).prop('id')] = $(this).offset().top; 
    } 
}); 

//track whether user scrolls up or down 
var prevScrollTop = $(document).scrollTop(); 

//monitor scroll event 
$(document).scroll(function() { 
    var currentScrollTop = $(this).scrollTop(); 
    if (currentScrollTop > prevScrollTop) { 
     downScroll(currentScrollTop); 
    } else { 
     //up 
    } 
    prevScrollTop = currentScrollTop; 
}); 

function downScroll(scrollTop) { 
    //find the first row that is visible on screen 
    for (var row in rowmarkers) { 
     if (rowmarkers[row] > scrollTop) { 
      //all rows after this can be updated 
      var updaterow = $('#' + row).prevAll('.marker:first'); 
      if (!updaterow.length) { updaterow = $('.marker:first'); } 
      //hardcoded # of rows to update 
      for (var i = 0; i < 20; i++) { 
       console.log($(updaterow).prop('id')); 
       updaterow = updaterow.next('tr'); 
       updaterow.not('.marker').addClass('updaterow'); 
      } 
      return; 
     } 
    } 
}