JS的定期执行和页面同步

在进行网页设计时,常需要在网页上定期执行一些操作。这里的定期操作并不是定期刷新,定期刷新时网页内容会全部重置,而我们希望的是在同一网页上动态变化。更进一步,定期的操作过程是向另一数据页面去获取数据。由于浏览器的缓存作用,有可能数据页面已经更新了,但取得的页面仍是数据变化前的内容,导致取得的数据一直没有变化。下面我们来描述这两个问题及解决办法。

主页面命名为page.html,初始时网页上有一个空表格。网页载入后Javascript定期执行一个获取数据过程,并将获取的数据动态填入表格行中。page.html的初始页面如下图:

 

数据页面命名为xml.php,动态提供数据。为了看清楚数据变化,我们使用当前时间。格式为:

1 <ROOT>
2 <RECORD>
3 2010年7月22日 07:51:12
4 </RECORD>
5  </ROOT>

如果page.html页面中的JS代码用以下形式:

1 <script type="text/javascript">
2  for (i=0; i<10; i++) {
3 FetchAndShow();
4 }
5 </script>

则1. 不能实现定时;2. 函数会全速运行,您将看不到表格行的动态增长过程,而是等该循环结束后一次性显示。如果循环变量不是10,而是一个很大的数据,则您可能需要等上很久才能看到运行结果。

我们可以采用如下结构的JS代码: 

1 <script type="text/javascript">
2 var clearObj = null;
3 FetchAndShow = function() {
4 // todo:要定期执行的代码
5
6 if (true||false) { // 如果满足停止执行的条件,则停止执行
7 clearInterval(clearObj);
8 }
9 }
10
11 $(document).ready(function(){
12 clearObj = setInterval("FetchAndShow()",1000); // 每隔1秒执行函数
13 }); // end document ready
14 </script>

前台页面的结构和思路都完成了,接下来看数据页面。如果xml.php中直接执行以下代码: 

1 <?php
2 $dom = new DOMDocument();
3 $dom_ROOT = $dom->createElement("ROOT");
4 $dom->appendChild($dom_ROOT);
5 $dom_RECORD = $dom->createElement("RECORD",date("Y/m/d H:i:s",time()));
6 $dom_ROOT->appendChild($dom_RECORD);
7
8 header("Content-type: text/xml");
9 $xml = $dom->saveXML();
10 echo $xml;
11 ?>

 则如果在浏览器中直接访问xml.php时,则正常;但在主页面中定期向它获取数据时,取得的数据会出现没有变化的情况。造成这种现象的原因是,浏览器对数据页面进行了缓存。当需要重复访问同一页面时,始终取得了缓存的同一页面。在PHP中解决办法是在输出之前,加上如下清除缓存的代码:

1 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
2 header("Cache-Control: no-cache, must-revalidate");
3 header("Pragma: no-cache");

下面给出实现最初希望的功能的完整代码(需要有jquery支持):

xml.php

1 <?php
2 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
3 header("Cache-Control: no-cache, must-revalidate");
4 header("Pragma: no-cache");
5
6 $dom = new DOMDocument();
7 $dom_ROOT = $dom->createElement("ROOT");
8 $dom->appendChild($dom_ROOT);
9
10 for ($i = 0; $i < 1; $i++) {
11 $dom_RECORD = $dom->createElement("RECORD",date("Y/m/d H:i:s",time()));
12 $dom_ROOT->appendChild($dom_RECORD);
13 }
14
15 header("Content-type: text/xml");
16 $xml = $dom->saveXML();
17 echo $xml;
18 ?>

page.html 

1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 <html xmlns="http://www.w3.org/1999/xhtml">
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <script type="text/javascript" src="jquery.js"></script>
6 <script type="text/javascript">
7 var clearObj = null;
8
9 init = function() {
10 $("#processlist>tfoot").append($("#processlist>thead>tr").clone());
11 $("#processlist>tbody>tr").hide();
12 }
13
14 FetchAndShow = function() {
15 v_maxProcess = parseInt($("#maxprocess").val());
16 v_totalProcess = parseInt($("#totalprocess").val());
17
18 $.ajax({
19 async:false,
20 url:"xml.php",
21 success:function(xml){
22 $(xml).find("RECORD").each(function(){
23 v_totalProcess++;
24
25 oTr = $("#processlist>tbody>tr:last").clone();
26 // 序号
27 currentNumber = parseInt($("#processlist>tbody>tr:first .number").text())+1;
28 $(".number",oTr).text(currentNumber);
29
30 // 时间
31 $(".timegap",oTr).text($(this).text());
32
33 $(oTr)
34 .prependTo($("#processlist>tbody"))
35 .show();
36
37 }); // end each
38
39 $("#totalprocess").val(v_totalProcess);
40 } // end function xml
41 }); // end ajax
42
43 if (v_totalProcess>=v_maxProcess) {
44 clearInterval(clearObj);
45 self.location = "page.html";
46 }
47 }
48
49 $(document).ready(function(){
50 init();
51 clearObj = setInterval("FetchAndShow()",2000);
52 }); // end document ready
53 </script>
54 <title>定期获取数据并更新页面</title>
55 </head>
56
57 <body>
58 <table width="100%" border="1">
59 <tr>
60 <td>最多处理记录数
61 <label>
62 <input name="maxprocess" type="text" id="maxprocess" value="5" size="5" maxlength="5" />
63 ,达到该值后将刷新页面重新启动!</label></td>
64 </tr>
65 <tr>
66 <td>当前处理数
67 <input name="totalprocess" type="text" id="totalprocess" value="0" size="5" maxlength="5" readonly="true" />
68 </td>
69 </tr>
70 </table>
71 <table width="100%" border="1" cellpadding="0" cellspacing="0" bordercolor="#CCCCCC" id="processlist">
72 <thead>
73 <tr>
74 <th>序号</th>
75 <th>时间</th>
76 </tr>
77 </thead>
78 <tbody>
79 <tr>
80 <th height="21" align="center" class="number">0</th>
81 <td align="center" class="timegap" title="时间">&nbsp;</td>
82 </tr>
83 </tbody>
84 <tfoot>
85 </tfoot>
86 </table>
87 </body>
88 </html>
89

最终效果图如下:

附:几种常用语言清除缓存方法

HTML:

1 <META HTTP-EQUIV="pragma" CONTENT="no-cache">
2 <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate">
3 <META HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT">

1 <META HTTP-EQUIV="expires" CONTENT="0">

ASP:

1 Response.Expires = -1
2 Response.ExpiresAbsolute = Now() – 1
3 Response.cachecontrol = "no-cache"

PHP:

1 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
2 header("Cache-Control: no-cache, must-revalidate");
3 header("Pragma: no-cache");

JSP:

1 response.setHeader("Pragma", "No-cache");
2 response.setHeader("Cache-Control", "no-cache");
3 response.setDateHeader("Expires", 1);
原文地址:https://www.cnblogs.com/jyginger/p/1782668.html