Search code examples
jqueryajaxslideshowcycle

Using jQuery Cycle and ajax to dynamically create a slide show - images don't load immediately


I'm currently trying to make a cheap, simple slide show navigation box for a client (something along the lines of what, say, the Red Sox or Gamespot use on their sites, but far, far simpler). So far, it's actually coming along nicely, with one problem - the images don't appear upon a first visit. They only appear after the page is reloaded. I think it may be some sort of runtime issue, or perhaps a cache issue, but I'm not sure how to fix it. My code:

PHP:

if (isset($_GET['start']) && "true" === $_GET['start'])
{
    $images = array();

    if ($dir = dir('images'))
    {
        //$count = 0;

        while(false !== ($file = $dir->read()))
        {
            if (!is_dir($file) && $file !== '.' && $file !== '..' && (substr($file, -3) === 'jpg' || substr($file, -3) === 'png' || substr($file, -3) === 'gif'))
            {
                $lastModified = filemtime("{$dir->path}/$file");
                $images[$lastModified] = $file;
                //$images["image$count"] = $file;
                //++$count;
            }
        }

        echo json_encode($images);
    }
    else { echo "Could not open directory"; }
}

HTML and JavaScript:

<!doctype html>
<html lang="en-us">
    <head>
        <title>jQuery Cycle test</title>
        <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
        <script type="text/javascript" src="js/jquery.cycle.all.min.js"></script>
        <style>
            #slideshow a { margin: 0; padding: 0; color: #fff; }
        </style>
    </head>

    <body>
        <div id="slideshow">
        </div>
    </body>

    <script type="text/javascript">
        $.get('slideshow.php', {start : "true"}, function(data){
            var images = JSON.parse(data);

            for(var image in images){
                $('#slideshow').append('<a href="images/' + images[image] + '"><img src="images/' + images[image] + '" alt="" /></a>');
            }

            $('#slideshow').cycle({
                fx: 'cover',
                direction: 'right',
                timeout: 3000,
                speed: 300
            });
        });
    </script>

</html>

I think I may need to delay the timing of the cycle function, or perhaps somehow force it to 'see' the images the first time through. I'm just not sure how to do it.


Solution

  • Since I wrote the original answer, I found that the same problem was occurring even with the timeout. I talked to the developer of the plugin on the jQuery forums, and his working example used $.getJSON rather than $.get. I switched to that, and it worked perfectly. I can only assume that there's some slight, subtle difference between how $.getJSON parses data and how I was doing it with the manual invocation of the parse function. Whether it's an actual code issue or timing issue of when the parsing is done remains a mystery.

    My solution:

    <!doctype html>
    <html lang="en-us">
        <head>
            <title>jQuery Cycle test</title>
            <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
            <script type="text/javascript" src="js/jquery.cycle.all.min.js"></script>
    
            <style>
                #slideshow a { margin: 0; padding: 0; color: #fff; display: block; }
                img { width: 305px; height: 278px; }
            </style>
        </head>
    
        <body>
            <div id="slideshow">
            </div>
        </body>
    
        <script type="text/javascript">     
            $.getJSON('slideshow.php', function(images){
                for(var i = 0; i < images.length; ++i){
                    $('#slideshow').append('<a href="images/' + images[i]['src'] + '"><img src="images/' + images[i]['src'] + '" alt="" /></a>');
                }
    
                $('#slideshow').cycle({fx: 'cover', direction: 'right', timeout: 3000, speed: 300});
            });
        </script>
    
    </html>