jQuery和PHP图像旋转器拼图

4

Jquery拼图

我有一个PHP脚本,可以从文件夹返回随机jpg图片的名称。这很好,因为我根本不需要重命名图片;我只需将它们放入文件夹中,随机器就可以工作。现在,我像这样调用脚本 - http://mydomain.com/images/rotate.php - 并在简单的网页重新加载时,它会交换图片。

但我想使用jQuery使其工作,我想让图片在大约十秒的间隔内交换成新图片,并且淡入淡出。

编辑1/23/10:

这通过交换spacer.gif来实现。可能有更优雅的解决方案,但这对我有效。Munch通过MidnightLightning的想法找到了答案:

function swapImage(){
  var time = new Date();
  $('#image').fadeOut(1000)
   .attr('src', 'http://mydomain.com/spacer.gif')
   .attr('src', 'http://mydomain.com/images/rotate.php?'+time.getTime())
   .fadeIn(1000);
}

var imageInterval = setInterval('swapImage()',10*1000); 

这是rotate.php文件:

<?php

$folder = '.';


    $extList = array();
    $extList['gif'] = 'image/gif';
    $extList['jpg'] = 'image/jpeg';
    $extList['jpeg'] = 'image/jpeg';
    $extList['png'] = 'image/png';


$img = null;

if (substr($folder,-1) != '/') {
    $folder = $folder.'/';
}

if (isset($_GET['img'])) {
    $imageInfo = pathinfo($_GET['img']);
    if (
        isset( $extList[ strtolower( $imageInfo['extension'] ) ] ) &&
        file_exists( $folder.$imageInfo['basename'] )
    ) {
        $img = $folder.$imageInfo['basename'];
    }
} else {
    $fileList = array();
    $handle = opendir($folder);
    while ( false !== ( $file = readdir($handle) ) ) {
        $file_info = pathinfo($file);
        if (
            isset( $extList[ strtolower( $file_info['extension'] ) ] )
        ) {
            $fileList[] = $file;
        }
    }
    closedir($handle);

    if (count($fileList) > 0) {
        $imageNumber = time() % count($fileList);
        $img = $folder.$fileList[$imageNumber];
    }
}

if ($img!=null) {
    $imageInfo = pathinfo($img);
    $contentType = 'Content-type: '.$extList[ $imageInfo['extension'] ];
    header ($contentType);
    readfile($img);
} else {
    if ( function_exists('imagecreate') ) {
        header ("Content-type: image/png");
        $im = @imagecreate (100, 100)
            or die ("Cannot initialize new GD image stream");
        $background_color = imagecolorallocate ($im, 255, 255, 255);
        $text_color = imagecolorallocate ($im, 0,0,0);
        imagestring ($im, 2, 5, 5,  "IMAGE ERROR", $text_color);
        imagepng ($im);
        imagedestroy($im);
    }
}

?>
6个回答

4
我认为这种方法的缺点在于,新图像需要加载一段时间,并且动画可能会因此有些古怪。如果文件有两个部分,其中一个是当 $_GET 值等于某个值时返回路径,另一个是当 $_GET 值未设置或等于其他值时返回图像,那将会更有利。这样您就可以预加载一系列图像,图像之间的动画效果会更加流畅。
话虽如此,我认为这种方法应该是可行的。
$(document).ready(function(){
   function swapImage(){
      var time = new Date();
      $('#image').fadeOut(1000)
       .attr('src', 'http://mydomain.com/images/rotate.php?'+time.getTime())
       .fadeIn(1000);
   }

   var imageInterval = setInterval('swapImage()',10*1000); 
});

时间使浏览器认为它正在获取新图像。

Spacer.gif

如果要使用黑色spacer完成此操作,建议将图像包装在div中,并为div设置#000背景颜色以与spacer匹配:

#image-wrap{background-color:#000;}

这将使图像真正变为黑色,而不是淡出到当前背景颜色,然后变成黑色并再次淡入。JavaScript代码与上面非常相似:

function swapImage(){
  var time = new Date();
  $('#image').fadeOut(1000)
   .attr('src', 'http://mydomain.com/spacer.gif')
   .attr('src', 'http://mydomain.com/images/rotate.php?'+time.getTime())
   .fadeIn(1000);
}

var imageInterval = setInterval('swapImage()',10*1000); 

在这里保留时间可能并不必要,但是嘿,这是另一个防止浏览器缓存“图像”的安全措施。


我认为这种方法很有价值。如果您尝试去除fadeOut/fadeIn动画,仅尝试每10秒用带有不断改变的后缀的URL交换源代码,那么firebug是否显示图像实际上正在重新加载?也许,与其直接从rotate.php到rotate.php,不妨先通过从rotate.php到spacer.gif再到rotate.php来"卸载"它? - MidnightLightning
这是一个很好的spacer.gif的想法。那么它的代码会是什么呢?一个黑色的spacer gif可能是一个不错的过渡效果:将颜色淡出到黑色,再淡入颜色,可以解决每次从rotate.php调用新图像而不必使用某种时间戳的问题。 - markratledge
这个有效!关键必须绕过某种图像缓存,即使我已经在.htaccess中禁用了缓存。MidnightLightning,我会看看能不能为你的想法得到一些积分。 - markratledge

2

由于您的php脚本正在返回新图像的源代码,因此最好避免使用load()函数,而是使用简单的ajax调用来替换图像的源。

var img=$('#image');//cache the element

function refreshNotification(){
  $.ajax({
    url: 'http://mydomain.com/images/rotate.php',
    success: function(src){
      img.attr({src: src});
    }
  });
}

setInterval(refreshNotification, 10000);

看起来这应该没问题,但实际上并没有。什么都没有显示出来,即使使用静态图像的URL而不是php脚本的URL也是如此。感谢您的帮助;我想不到还有什么别的尝试了... - markratledge
请确保使用 www.mydomain.com 进行测试,有关脚本的某些内容会发出警告...或者尝试消除域名部分并改用 images/rotate.php。如果您在更深的目录中,则使用 \ 替换 http://mydomain.com/。您可能需要进行调整。 - Val
这似乎应该是一个简单的修复。ajax调用返回了什么?它只是一个图像的源或者一个<img>标签吗?一旦交换完成,firebug会显示受影响的图像的src是什么? - czarchaic
这正在变成一个史诗般的事情 :) Firebug 显示 get 请求正常触发,而 html 显示图像文件的原始源代码... - markratledge
为什么/如何会起作用?如果我理解正确,您正在将响应内容的一部分(其内容类型为“图像”)分配给src属性,而该属性应该是一个字符串URL...? - Richard JP Le Guen

1

类似这样的方法可能会有效,假设你的PHP脚本仅返回图像的URL:

$(document).ready(function(){
    window.setInterval(switchImage, 10000);

    function switchImage() {
        var rn = Math.floor(Math.random() * 100000)
        $.get('http://mydomain.com/images/rotate.php', 
              { n: rn }, 
              receiveNewImage);
    }

    function receiveNewImage(src) {
        $('#image').fadeTo(1000, 0.0, function() { switchAndFadeIn(src); } );
    }
    function switchAndFadeIn(newSrc) {
        $('#image').attr('src', newSrc).fadeTo(1000, 1.0);
    }
});

编辑:添加随机参数。

编辑:在您的 PHP 中,类似这样的代码是否有帮助?

header("Cache-Control: no-cache, must-revalidate");
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Expires data in the past

似乎这应该可以正常工作,但实际上并没有。什么都没有显示出来,即使使用静态图像的URL而不是php脚本的URL也是如此。感谢您的帮助;我想不到还有什么别的尝试了... - markratledge
你没有收到任何错误吗?你是否使用Firebug进行调试?AJAX请求是否真正执行?它返回了预期的值吗? - Tom Bartel
是的,应该提供更多细节; 熬夜了。今天早上它有点工作; 我的标题中有垃圾字符。它淡入淡出一个图像,并且Firebug显示Get请求正在触发。一定是与图像的返回URL有关吗?现在我意识到图像的URL始终相同- http://mydomain.com/images/rotate.php - 但图像不同。当我直接在浏览器中转到ttp://mydomain.com/images/rotate.php时,每次(非jQuery)重新加载都会得到不同的图像。所以这是我一开始没有意识到的差异...感谢您的帮助。 - markratledge
只是根据我有限的jQuery知识猜测:我们需要进行完整的ajax调用来获取图像,而不是使用$.get,因为尽管图像将从php脚本中改变,但图像URL仍然保持相同吗? - markratledge
这真是一个史诗级的问题 :) Firebug 显示 GET 请求已经正常发送,HTML 显示了图像文件的原始代码。我在 htaccess 中禁用了图像缓存,但没有起到作用... - markratledge
显示剩余3条评论

1

swapImage() 函数定义在 $(document).ready() 块之外怎么样?

<script type="text/javascript" scr="path/to/jquery.js"></script>
<script type="text/javascript">
function swapImage(){
    var time = new Date();
    $('#rotate').fadeOut(1000)
     .attr('src', 'rotate.php?'+time.getTime())
     .fadeIn(1000);
}
$(document).ready(function(){
  var imageInterval = setInterval('swapImage()',5000);
});
</script>

<img src="rotate.php" id="rotate" />

这几乎就做到了... Firebug 显示脚本正常运行,我可以得到第一张图片,然后后续的图片就不见了,但是我确实得到了缺失的图片“?”(它会淡入淡出),比之前多了。缺失图片的原因是 Firebug 中的图像 URL 附加了时间戳,即 rotate.php1264184509211。但是删除时间戳也不起作用。Firebug 显示重新加载正在发生,但 URL 只有 rotate.php,什么也没有发生。 - markratledge
如果是 rotate.php1234567890,应该改为 rotate.php?1234567890。 - robertbasic
这会有所不同,因为没有“?”符号,服务器会寻找名为rotate.php1234567890的文件,但是有“?”符号后,它会寻找rotate.php并通过$_GET传递参数。对我而言,这个例子完全正常...你使用的jQuery版本是什么?路径设置正确吗? - robertbasic

0
$("#image").each(function({
$(this).fadeOut(function() { 

$(this).attr("src", "http://mydomain.com/images/image.jpg"); 
$(this).load(function() { $(this).fadeIn(); }); // this should be on the bottom....
}); 
})

检查JQEach上的每个函数

我已经更新了脚本,我认为它应该可以工作,因为你正在等待图像加载,但是它没有源代码... 看看这个 > <img onerror="alert('there was an error') />" 如果你得到错误,那就意味着源不存在。顺便说一句,如果你计划使用多个图像,就不应该使用#image,因为在你的HTML中只能有一个唯一的ID,否则会产生冲突

希望这可以帮助到你


看起来应该没问题,但实际上不行。什么都不显示,甚至使用静态图像的URL也不行。感谢您的帮助;我想不出还有什么尝试的了... - markratledge
仍然无法使其工作,并且也没有抛出错误。只使用了一个#image。它如何计时淡入/淡出间隔? - markratledge
$(this).fadeOut(1000,function() { 速度参数在回调函数之前...http://docs.jquery.com/Effects/fadeOut,因此您将会收到一个错误。 - Val

0

您的设置缺少告诉jQuery不要缓存AJAX请求的步骤。可以在AJAX调用中添加一个'cache' parameter参数来强制获取新副本:

$.ajax({
  url: 'http://mydomain.com/images/rotate.php',
  cache: false,
  success: function(src){
    img.attr({src: src});
  }
});

Firebug显示了这些Get请求的触发,但图像没有显示,只显示图像的原始代码。它确实旋转了图像,但图像没有显示,只显示源代码。 - markratledge
哦,这行不通,因为AJAX正在获取图像的数据,这是AJAX调用的结果,而不是图像的URL,这就是我推入'src'属性的内容(圆钉,方孔;无论如何都不会起作用,即使随机更改)。 给一些时间来思考,我认为Munch的想法是不使用AJAX,而是使用随机后缀可能是正确的方法,如果加以改进。 - MidnightLightning

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