IT源码网

用Ajax实现表格动态滚动

developer 2021年04月03日 程序员 403 0
一、概述

    在本文中将讨论如何实现一个基于Ajax的可滚动的表格,在这个表格中,每一行都是从服务器动态获得的,当用户滚动时,整个页并不刷新,而只是局部刷新。这项技术对于实现拥有很多动态数据的表格页是非常有效和便利的。例如,当重表调整页的尺寸后,表格数据将会平滑地滚动。这是由于表格中的数据是通过AJAX从服务端异步获得的,然后由JavaScript对数据进行分析,并动态地插入每一行,而XMLHttpRequest对象用于向服务端发送请求,最后由CSS控制显示风格。
    动态滚动表格的实现主要得意于现代的浏览器引入了XMLHttpRequest对象。这使得JavaScript对象可以使用异步的方式向服务端发送请求,并从服务端接收响应,而这一切都不需要刷新整个网页。更在很多的Web2.0站点都使用了很多AJAX技术来使界面变得更丰富多彩,其中XMLHttpRequest在这些站点和这些动态的网页中被广泛地使用。
    可滚动的表单是一个非常好的富客户端接口,它使用了Web2.0的技术来为用户展现Web内容。动态滚动技术的实现从某种程度上也取决于最新的CSS2标准的推出,这个新的CSS标准现在已经被很多流行的浏览器支持。在本文提供的代码中,我将介绍如何在屏幕的一部分实现可动态滚动的表格,但如果读者所使用的浏览器不动态最新的CSS标准,而只动态AJAX,这个动态表格将变成充满整个页面,而不是屏幕的一部分。
    图1是一个Google读者网站的一个动态表格的例子。要注意的是在图1的截屏上一100项记录,通过移动垂直滚动条可看以更多的记录,当显示到140条时(如图2所示),滚动条的大小开始变化 。这时,所有其他的记录仍然保持在本页的同样的位置。



                一个显示100条记录的动态滚动表单



     图在表单后又新加了40条记录,注意滚动条的位置
二、如保实现动态表单
    为了使任何HTML元素(在本文中是表格)可滚动,需要使用一个可滚动的区域,在这里是DIV,这个元素应该比表格的实际高度小。如一个DIV的高度为100px,包含一个高度为200px的表格,这样才可以使表格滚动。下面的代码演示了div和table的使用:

<div style="height:100px; width:50px;
            overflow:auto; overflow-x:hidden;">
   <table style="height:200px;">
      <tr><td>vlad</td></tr>
   </table>
</div>



图3 产生滚动行为的例子代码

    要注意的是,如果我们将table和div分开写,那么就只有div滚动,而不是表在滚动。让我们先看看如下的代码:
 
  
  
   
<table style ="height:50px; width:100px; overflow:auto;overflow-x:hidden;"> <tr><td><p>vlad 1</p></td></tr> <tr><td><p>vlad 2</p></td></tr> <tr><td><p>vlad 3</p></td></tr> <tr><td><p>vlad 4</p></td></tr> <tr><td><p>vlad 5</p></td></tr> </table>

 
  
  
   
<hr/> <div style ="height:100px; width:100px; overflow:auto;overflow-x:hidden;"> <p>Vlad 1 </p> <p>Vlad 2</p> <p>Vlad 3</p> <p>Vlad 4</p> <p>Vlad 5</p> </div>
4 显示了上述代码的运行结果:

图4 

我们注意到table的高度是50,但它仍然不滚动。
 
    上面代码的两个CSS属性:overflow auto和overflow-x:hidden,实际上是将滚动条显示在div的右侧。不过浏览器的CSS引擎必须支持这两个属性,否则,这个表将不会有滚动条。
    如果div中的内容落在了div的外面,可能的原因很多,如margin为负、使用了绝对位置、内容超过了width/height等等,而overflowoverflow-x属性只是描述了内容超过div的宽度应该如何去做。
   
这些CSS属性仅仅定义了divtable的外观,而不是带有滚动属性的JavaScript API接口。为了充分理解一个动态表单的实现,我们需要知道测量HTML元素在网页中的尺寸和位置的属性。这些属性可以通过JavaScript用可编程的方式来操作,更值得庆幸的是,这些API在目前的主要浏览器中都可以使用。
三、HTML元素属性
 
在网页的中心是HTML元素属性的表单,代码位于页中心的HTML BODYDIV中。我们从图5看出,这页有很多这类东西,但是我们最感兴趣的是scrollTopscrollHeightclientHeight




图5 Div的属性的可视化描述

    这个scrollTop属性指定了可视区域(被div的height和width定义的)的内容的上边界的位置,当用户滚动时,scrollTop将确定内容移动的距离(单位是像素)。这个scrollHeight属性指定了inner元素的实际高度(单位是像素),而clientHeight指定了可视区域的实际高度。在本文的例子中,可视区域是outer div元素,而内容是inner表。Height和Top属性并不能解决元素的border、margin或padding,如果我们的元素有这些属性的任何一个,可以使用其他类似的属性代替。和height类似,由width属性来处理水平滚动计算。
    第一个被放置在页上的元素都有这些属性,以及使用这种方式的元素看起来都以来于这些属性。图6显示了一个关于div属性的简单例子。


                                   图6 有滚动功能 的div


四、实现动态滚动表格
    为了实现一个动态表格,我现在已经将表格的显示部分放到了叫"scrolltable"CSS中,将建立了一个id"new_items_div"div和一个id"new_items"table。叫"status"div的目的是为了显示不同的信息。这段html代码如下:

 
            
            
             
< div id ='status' ></ div > < div id ="new_items_div" style ="height:500px;" class ="scrolltable" > < table id ="new_items" border ="0" cellpadding ="0" cellspacing ="0" > < tbody > </ tbody > </ table > </ div >

实现滚动逻辑的代码的第一部分是自动追加更多的行,这些行包括用户已经滚动过的行。为了实现这个功能,我建立了一个JavaScript函数detectScroll(),这个函数每0.5秒执行一次。除了这种方法,还可以为滚动事件建立一个处理事件的函数,并和div绑定。这个startPolling函数当整个页面装载时被调用,并开始周期性地调用detectScroll()函数。

    在这个算法中,将探测滚动位置,并检查所滚动的距离是否大于等于可视区域高度。我还加了20个象素来将滚动条的尺寸计算在内,以确保滚动条可以在适当的位置出现。
    如果用户在向下滚动后向上滚动,并没有新行出现,而只是将已经显示过的数据重新显示。下面是完整的JavaScript代码:
 
           
           
            
function startPolling(){ pollID = setInterval( " detectScroll() " , 500 ); } function detectScroll(){ var intElemScrollHeightOuter = document.getElementById( " new_items_div " ).clientHeight; var intElemScrollHeightInner = document.getElementById( " new_items " ).scrollHeight; var intElemScrolled = document.getElementById( " new_items_div " ).scrollTop; var height = intElemScrollHeightInner - intElemScrollHeightOuter; if (intElemScrolled >= height - 20 ) { // alert("You are at " + document.getElementById("new_items").scrollTop + " pixels. adding rows..."); document.getElementById('status').innerHTML = " Showing&nbsp;<b> " + (viewCnt + 5 ) + " </b>&nbsp;items " ; fetchAction(viewCnt); viewCnt += 5 ; } return true ; } fetchAction( 0 ); startPolling(); </ script >

 

如果当detectScroll执行时返回true。那么会有一个新的JavaScript函数fetchAction被调用。而且还需要使用整个行数来更新div的"status"。

fetchAction函数通过异步的方式访问服务器,并使用XMLHttpRequest对象来分派一个回调函数readFeed来处理服务端的响应。我们在这里不用管服务端是如何实现的,只要知道服务端返回了一个合法的XML就可以了,服务端可以使用任何语言来完成这个任务。在本例中使用了PHP来实现服务端,读者也可以根据自己的喜好使用Java.NETfetchAction()函数的代码如下:

 


 

 
           
           
            
function fetchAction(si) { var xmlHttp = getXmlHttpObject(); if (xmlHttp == null ) { alert('警告,浏览器不支持XmlHttpObject()'); return ; } xmlHttp.onreadystatechange = function (){ if (xmlHttp.readyState == 4 || xmlHttp.readyState == " complete " ){ readFeed(xmlHttp); xmlHttp = null ; } } try { url = 'fetch_items.php ? ri = ' + (Math.floor(Math.random() * 10000000 )) + ' & si = ' + si; xmlHttp.open( " GET " ,url, true ); xmlHttp.send( null ); } catch (ex){ document.getElementById( " status " ).innerHTML = ex; clearInterval(pollID); } }
 
评论关闭
IT源码网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!