Displaying an image’s alt title and caption inside a fancybox window. Working, but showing the same alt and caption for each image

Your problem is with your foreach loops… here:

 if ($images) {
    foreach($images as $image) {
        $caption = $image->post_excerpt;
    }   
 }

and here:

 //alt title
 foreach ($images as $attachment_id => $image) {
    $img_alt = get_post_meta($attachment_id, '_wp_attachment_image_alt', true); 
 } 

Basically what is happening is that your $caption and $img_alt variables are being set at each iteration of your loop, but you are not returning or saving the new value. Instead you are just letting the loop continue running and you $caption and $img_alt variables are being set to the next value (making your loop worthless).

What you need to do is this. First move your PHP loop outside of your callback, and save your captions and img_alts to two new arrays. It should look something like this:

<?php 

    $images = get_children( array(
        'post_parent' => $post->ID, 
        'post_status' => 'inherit', 
        'post_type' => 'attachment', 
        'post_mime_type' => 'image', 
        'order' => 'ASC', 
        'orderby' => 'menu_order ID'
    ));

    //caption
    $captions = array();
    if ($images) {
        foreach($images as $image) {
            $captions[] = $image->post_excerpt;
        }   
    }

    //alt title
    $img_alts = array();
    foreach ($images as $attachment_id => $image) {
        $img_alts[] = get_post_meta($attachment_id, '_wp_attachment_image_alt', true); 
    }    

    ?> 

Now output the values of the captions and javascript into two hidden lists on the page. The reason for outputting them is so that we can easily grab the text using some javascript later.

<ol id="captions">
    <?php
    foreach ($captions as $caption){
        echo '<li>' . $caption . '</li>'; 
    };
    ?>
</ol>

Do the same thing as above with your img_alts.

Now rewrite the callback in your javascript function to look something like this. Here I am assuming that ‘currentIndex’ matches the whatever the index number of the currently displayed image is:

function(title, currentArray, currentIndex, currentOpts) {

    // get your caption
    var caption = jQuery('#captions').get(currentIndex).text();

    // get your img alt
    var img_alt = jQuery('#img_alts').get(currentIndex).text();

    var html="<span class="caption">" + caption + '</span>';
    html += '<span class="img_alt">' + img_alt + '</span>';

    return html;
}

I have not checked to see if this code works so there may be some errors in it, but if you follow my logic something like this should solve your problem. Hope this helps.