• 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);
  • 相关阅读:
    js事件分类
    过3s弹出广告条,点叉号关闭
    js进阶
    js入门
    html
    R Markdown + Infinite Moon Reader + 编辑实时更新
    png转ico+windows图标+GIMP
    微生物+计算细胞倍增时间
    使用Mathjax网页插入公式
    Firefox+zoom+全局缩放比例
  • 原文地址:https://www.cnblogs.com/jyginger/p/1782668.html
Copyright © 2020-2023  润新知