图像闪烁ajax轮询

image flicker ajax polling

本文关键字:轮询 ajax 闪烁 图像      更新时间:2023-09-26

我目前正在使用ajax轮询定期从数据库中获取新数据,并将其显示给用户。它工作得很好,只是有时,获取的图像开始闪烁,然后闪烁突然停止。以下是获取数据的JavaScript:

function loadLog(){     
    $.ajax({
        url: "stream.php",
        cache: false,
        success: function(html){
$("#inner").html(html);         
        }
    });
}
setInterval (loadLog, 2500);

stream.php文件包含基本的sql命令,用于检查数据库中的新数据。因此,这些命令每2.5秒调用一次。如果post类型是一张图片,则会附带一条语句,例如:user_name posted a new image,xseconds ago。语句从不闪烁,但图像会闪烁。有没有办法阻止图像的闪烁?(有趣的是,如果数据库已经有图像,那么只有新发布的图像会闪烁,而旧的图像则不会。因此,如果总共有3个图像,两个旧的和一个新的,则新的图像会闪动,而其他图像则不会,尽管整个脚本都在轮询,而不是特定的图像。)

从过去几天开始,我一直在处理同样的问题,最后我得到了以下示例代码。

您需要的是将上次更新的time-stamp传递给新的请求,并根据该time-stamp查找传递的time-stamp和当前time-stamp之间的记录。

Index.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>testing comet</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="stylesheet" href="css/style.css" />
        <script type="text/javascript" src="js/jquery.js"></script>
    </head>
    <body>
    <div id="content"></div>
<script type="text/javascript">
    var Comet = function (data_url)
    {
        this.timestamp = 0;
        this.url = data_url;  
        this.noerror = true;
        this.connect = function()
        {
            var self = this;
            $.ajax(
            {
                type : 'post',
                url : this.url,
                dataType : 'json', 
                data :
                {
                    'timestamp' : self.timestamp
                },
                success : function(response)
                {
                    self.timestamp = response.timestamp;
                    self.handleResponse(response);
                    self.noerror = true;          
                },
                complete : function(response)
                {
                    if (!self.noerror)
                    {
                        setTimeout(function(){ comet.connect(); }, 5000);           
                    }
                    else
                    {
                        self.connect(); 
                    }
                    self.noerror = false; 
                }
            });
        }
        this.disconnect = function() {}
        this.handleResponse = function(response)
        {
            $('#content').append('<div>' + response.msg + '</div>');
        }
        this.doRequest = function(request) {
            $.ajax(
            {
                type : 'post',
                url : "index.php",
                data :
                {
                    'msg' : request,
                    'submit' : "Send"
                }
            });
        }
    }
    var comet = new Comet('./backend.php');
    comet.connect();
</script>
</body>
</html>

backend.php

<?php
    $filename  = dirname(__FILE__).'/data.txt';
    $msg = isset($_GET['msg']) ? $_GET['msg'] : '';
    if ($msg != '')
    {
        file_put_contents($filename,$msg);
        die();
    }
    $lastmodif    = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0;
    $currentmodif = filemtime($filename);
    while ($currentmodif <= $lastmodif) // check if the data file has been modified
    {
        usleep(10000); // sleep 10ms to unload the CPU
        clearstatcache();
        $currentmodif = filemtime($filename);
    }
    $response = array();
    $response['msg']       = file_get_contents($filename);
    $response['timestamp'] = $currentmodif;
    echo json_encode($response);
    flush();
?>

您所需要做的就是将txt file time modification替换为mysql查询。

用mysql替换txt文件的示例代码

<?php
date_default_timezone_set('Asia/Kolkata');
$connection = mysql_connect('localhost','root','')or die(mysql_error());
$database   = mysql_select_db('stackoverflow')or die(mysql_error());
function get_date()
{
    $query = mysql_query("show table status from stackoverflow like 'last_update'")or die(mysql_error());
    $row = array();
    while($result = mysql_fetch_assoc($query))
    {
        $row[] = $result;
    }
    return strtotime($row[0]['Update_time']);
}

$lastmodif    = isset($_POST['timestamp']) ? $_POST['timestamp'] : 0;
$currentmodif = get_date();
while ($currentmodif <= $lastmodif)
{
    usleep(10000);
    clearstatcache();
    $currentmodif = get_date();
}
$query_db = mysql_query("SELECT UNIX_TIMESTAMP(last_update.created) AS DATE,last_update.* FROM last_update WHERE UNIX_TIMESTAMP(last_update.created) BETWEEN '".$lastmodif."' AND '".$currentmodif."'")or die(mysql_error());
$row_db = array();
$response = array();
while($result_db = mysql_fetch_assoc($query_db))
{
    $response['msg'][]       = $result_db['title'];
}
$response['timestamp'] = $currentmodif;
$response['lastmodif'] = $lastmodif;
echo json_encode($response);
flush();

希望这对你有帮助。

我的猜测是,这是因为您每次都要替换#innerdiv的HTML,因此它将被重新渲染。

最优雅的方法是只获取新项目(通过将时间戳参数传递给stream.php,即stream.php?timestamp=X,并且只返回自时间戳以来的提要中的项目,然后返回.prepend();,该内容包含在#inner分区中。

另一个建议是将该内容加载到一个新的隐藏div中,使其完全呈现,然后快速显示/隐藏旧的div。

尝试只更新#inner的一部分。例如,如果图像没有更改,则只更新文本。如果图像已更改,请将其替换为新图像。我想在这种情况下,你不会注意到闪烁的效果。还要查看这些图像的http标头-可能有不正确的Expires、Last Modified等标头,浏览器会多次加载相同的图像。