0

I'm using Cycle2 to create a slideshow of images loaded from a folder via PHP. You can see the live site here: http://www.element17.com/.

These images can be in a number of different folders ("albums"), and so I've created the following function to switch from one album to another:

$('.togglealbum').click(function() {
    $('#slideshow').cycle('destroy');
    $('#slideshow').html('<div class="cycle-overlay custom" id="info"></div>'+all[(this).id]);
    $('#slideshow').cycle();
    if ($('#play').is(':visible')) {
        $('#slideshow').cycle('pause');
    } else {
        $('#slideshow').cycle('pause').delay(3000).cycle('resume');
    }
    $('.togglelink,.toggleinfo').removeClass('active').addClass('fadein');
    $('#albums').fadeToggle('fast');
    $('.togglealbum').removeClass('cycle-pager-active');
    $(this).addClass('cycle-pager-active');
    $.cookie("currentalbum",(this).id,{expires:7});
});

The problem I'm having is that when the new images are loaded in (via this line: $('#slideshow').html('<div class="cycle-overlay custom" id="info"></div>'+all[(this).id]);), the slideshow starts playing basically immediately, but no images are displayed until they're all downloaded.

This isn't necessarily a problem except that usually what seems to happen is that the first image is displayed for maybe a second or two and then transitions to the next slide (the transitions are on a 7 second timeout). If you were on a slower internet connection, I suppose you might not even see the first slide.

How can I prevent this from happening? I've tried to delay the start of the slideshow but this seems really inelegant, and I'd greatly prefer for the first image to be shown as soon as it's loaded, but I'm not sure how to do that.

The corresponding code for that line above follows:

<?php
if(isset($_COOKIE["currentalbum"])) {
    $currentalbum = $_COOKIE["currentalbum"];
} else {
    $currentalbum = "gallery/01_New";
}
$photolist = getphotolist($currentalbum);
$directory = 'gallery/*';
$subfolders = glob($directory);
foreach($subfolders as $subfolder) {
    if(!file_exists($subfolder."/thumbs")) {
        mkdir($subfolder."/thumbs", 0777);
    }
    $photos = glob($subfolder.'/*.[Jj][Pp][Gg]');
    foreach($photos as $photo) {
        $photoname = explode('.',basename($photo));
        $thumbnail = $subfolder.'/thumbs/'.$photoname[0].'_thumb.jpg';
        if (!file_exists($thumbnail)) {
            makethumb($photo,$thumbnail,150);
        }
    }
    $all[$subfolder] = getphotolist($subfolder);
}
$all_json = json_encode($all);
?>

Thanks very much!

NaOH
  • 449
  • 1
  • 10
  • 23
  • Try using the $(window).load() function to wait til everything is loaded before running your code. http://stackoverflow.com/questions/544993/official-way-to-ask-jquery-wait-for-all-images-to-load-before-executing-somethin – Brandon Kindred Nov 14 '13 at 18:53
  • This doesn't work when new images are loaded in I believe, as the browser doesn't seem to indicate that it's loading anything (no spinning wheels or anything). I have tried this before to no avail. – NaOH Nov 14 '13 at 18:54
  • If you are using an ajax call to get this then your code should be called from the success function – Brandon Kindred Nov 14 '13 at 18:58

1 Answers1

2

Yo can use a data attribute to delay the slideshow until all images are loaded:

$('#slideshow').html('<div class="cycle-overlay custom" data-cycle-loader="wait" id="info"></div>'+all[(this).id]);
             Edit: This attribute, but not here though: ^^^^^^^^^^^^^^^^^^^^^^^^

Check the documentation for more options.

Edit: Silly mistake, you need to add the data attribute to your #slideshow element, not to a child of it.

So it would be something like this in the original html:

<div id="slideshow" data-cycle-loader="wait"></div>
jeroen
  • 91,079
  • 21
  • 114
  • 132