Головоломка с ротатором изображений на jQuery и php
Вопрос
JQuery-головоломка
У меня есть PHP-скрипт, который возвращает имя случайного изображения jpg из папки.Это приятно, потому что мне вообще не нужно переименовывать изображения;Я просто закидываю их в папку и рандомайзер работает.Прямо сейчас я вызываю сценарий так: http://mydomain.com/images/rotate.php - и при простой перезагрузке веб-страницы изображения меняются местами.
Но я бы хотел, чтобы это работало с jQuery, поскольку я хотел бы, чтобы изображения менялись на новые с интервалом в десять секунд или около того, а также постепенно появлялись и исчезали.
Редактирую 23.01.10:
Это работает путем замены spacer.gif.Возможно, есть более элегантное решение, но меня это устраивает.Мунк понял это благодаря идее 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);
}
}
?>
Решение
Недостатком такого подхода я считаю то, что для нового изображения потребуется период загрузки, и из-за этого анимация может быть немного странной.Может быть полезно иметь две части этого файла, где возвращается путь, если значение $_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
Чтобы сделать это с помощью черной прокладки, я бы рекомендовал обернуть изображение в элемент div и присвоить ему цвет фона #000, соответствующий разделителю:
#image-wrap{background-color:#000;}
Это приведет к тому, что изображение фактически станет черным, а не исчезнет до текущего цвета фона, изменится на черный и снова исчезнет.JS будет очень похож на приведенный выше:
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);
Хранить там время, вероятно, не обязательно, но, эй, это еще одна защита от кэширования браузером «изображения».
Другие советы
Поскольку ваш 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);
Что-то вроде этого может сработать, если предположить, что ваш 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
Как насчет определения 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" />
$("#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....
});
})
Проверьте каждую функцию на JQКаждый
Я обновил скрипт, думаю, он должен работать, потому что вы ждете загрузки изображения, но у него нет источника...проверьте это > <img onerror="alert('there was an error') />"
если вы получаете сообщение об ошибке, это означает, что источник не существует.Кстати, вам не следует использовать #image, если вы планируете использовать несколько изображений, поскольку в вашем html может быть один уникальный идентификатор, иначе вы получите конфликты.
надеюсь это поможет
В вашей настройке отсутствует шаг указания jQuery не кэшировать запрос AJAX.Есть параметр кэша это можно добавить к вызову AJAX, чтобы заставить его получить новую копию:
$.ajax({
url: 'http://mydomain.com/images/rotate.php',
cache: false,
success: function(src){
img.attr({src: src});
}
});