刷新div,但仅在php文件中有新内容时才刷新。

6

背景信息

我目前正在摆弄一些PHP和AJAX,试图让代码工作自动刷新包含评论的div(每10秒),

这是我用来刷新div的javascript代码..

<script type="text/javascript">// <![CDATA[
$(document).ready(function() {
        $.ajaxSetup({ cache: false }); 
            setInterval(function() {
                    $('#content_main').load('/feed_main.php');
        }, 5000);  
});
// ]]></script>

代码将填充名为“content_main”的div,该div位于feed_main.php中,基本上访问数据库并输出最新评论...

问题

如果它内部的数据自上次加载以来没有更改,是否可以仅加载“content_main” div?

我的逻辑

因为我对javascript和AJAX相对较新,所以不太知道如何做到这一点,但我的逻辑是:

第一次运行时..

  • 从feed_main.php文件加载数据
  • 创建一个唯一值(例如哈希值?)来标识3个唯一的评论

每次运行时...

  • 从feed_main.php文件加载数据
  • 创建一个新的唯一值
  • 检查此值与先前的值
  • 如果它们相同,则不要刷新div,只需保持现状,但如果它们不同,则刷新..

我之所以想这样做,是因为评论通常附有图片,每次看到图片重新加载都很烦人。

非常感谢您提供的任何帮助。


你可以先从 AJAX 调用中读取数据,然后将其与 div 的内容进行比较。 - Ravi Y
@ryadavilli 是的,这就是我想的,你能详细说明一下我该怎么做吗?就像我说的,我的JS知识非常有限 :S - sotirios9
类似长轮询、Comet 对我来说是解决方案。 - Dr. Dan
您能否提供一个例子呢,@Dr.Dan? - sotirios9
基本上,Comet是一种 Web 应用程序模型,在此模型中,长时间持有的 HTTP 请求允许 Web 服务器向浏览器推送数据,而不需要浏览器明确请求它。更多信息请参见 http://en.wikipedia.org/wiki/Comet_(programming) 和示例:http://www.zeitoun.net/articles/comet_and_php/start。 - Dr. Dan
你能发布 feed_main.php 的代码吗?这样我们就可以看到你在那一端尝试了什么。 - IROEGBU
3个回答

5

我不久前也遇到过类似的问题,我猜你在服务器端使用了mysql或其他数据库来存储评论?

我通过在mysql表中首先添加时间戳整数列来解决我的问题,然后当我添加新行时,我只需简单地使用time()保存当前时间。

mysql插入行示例:

$query = "INSERT INTO comments (name, text, timestamp) VALUES ('". $name ."', '". $text ."',". time() .");";

第二步是将您从服务器端发送的数据进行json_encode:
$output = array();

if ($html && $html !== '') {   // do we have any script output ?
  $output['payload'] = $html;  // your current script output would go in this variable
}
$output['time'] = time();      // so we know when did we last check for payload update

$json = json_encode($output, ((int)JSON_NUMERIC_CHECK)); // jsonify the array
echo $json;                    // send it to the client

因此,现在您的服务器端脚本返回的不再是纯html,而是类似于以下内容:
{
  "payload":"<div class=\"name\">Derpin<\/div><div class=\"msg\">Foo Bar!<\/div>",
  "time":1354167493
}

您可以很简单地在Javascript中获取数据:

您可以使用以下代码:

<script type="text/javascript"> // <![CDATA[

var lastcheck;
var content_main = $('#content_main');

pollTimer = setInterval(function() {
  updateJson();
}, 10000);

function updateJson() {
  var request = '/feed_main.php?timestamp='+ (lastcheck ? lastcheck : 0);

  $.ajax({
    url: request,
    dataType: 'json',
    async: false,
    cache: false,
    success: function(result) {
      if (result.payload) {        // new data
        lastcheck = result.time;   // update stored timestamp
        content_main.html(result.payload + content_main.html()); // update html element
      } else {                     // no new data, update only timestamp
        lastcheck = result.time;
      }
    }
  });
}

// ]]> </script>

这基本上处理了服务器和客户端之间的通信,现在您只需查询数据库,如下所示:
$timestamp = 0;
$where = '';

if (isset($_GET['timestamp'])) {
  $timestamp = your_arg_sanitizer($_GET['timestamp']);
}

if ($timestamp) {
  $where = ' WHERE timestamp >= '.$timestamp;
}

$query = 'SELECT * FROM comments'. $where .' ORDER BY timestamp DESC;';

时间戳会被传递来回,客户端始终发送服务器在前一次查询中返回的时间戳。你的服务器只会发送自上次检查以来提交的评论,并且你可以像我所做的那样将它们作为html的开头。 (警告:我没有对此进行任何合理性控制,你的评论可能会变得非常长)由于您每10秒轮询新数据,因此您可能希望考虑通过ajax调用发送纯数据以节省大量带宽(仅包含时间戳的JSON字符串,约为20个字节)。然后,您可以使用JavaScript生成HTML,这也具有将很多工作从服务器转移到客户端的优点:)。您还将获得更精细的控制权,可以一次显示多少评论。
我做了一些相当大胆的假设,您需要修改代码以适应您的需求。如果您使用我的代码,而您的猫|计算机|房子碰巧爆炸了,您可以保留所有碎片:)

3
这个怎么样:
<script type="text/javascript">
    // <![CDATA[
    $(function () {

        function reload (elem, interval) {
            var $elem = $(elem);
            // grab the original html
            var $original = $elem.html();
            $.ajax({
                cache : false,
                url : '/feed_main.php',
                type : 'get',
                success : function (data) {
                    // compare the result to the original
                    if ($original == data) {
                        // just start the timer if the data is the same
                        setTimeout(function () {
                            reload(elem, interval)
                        }, interval);
                        return;
                    }
                    // or update the html with new data
                    $elem.html(data);
                    // and start the timer
                    setTimeout(function () {
                        reload(elem, interval)
                    }, interval);
                }
            });
        }

        // call it the first time
        reload('#content_main', 10000);
    });
    // ]]>
</script>

这只是一个启发性的想法,它并没有涉及错误或超时处理。


0

最好且易懂的代码

setInterval(function()
    { 
        $.ajax({
          type:"post",
          url:"uourpage.php",
          datatype:"html",
          success:function(data)
          {
            $("#div").html(data);
          }
        });
    }, 5000);//time in milliseconds 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接