Uploading Media
In this particular case, the client can use the Media Uploader found on a post’s editor screen. As you can see in figure 1 the post allows multiple images to be inserted into the custom post we’ve created. Once the images are within the post as attachments we can run a loop in our PHP to grab the images and display them within our desired markup pattern.

Retrieving Media
The PHP seen in figure 2 is placed within single-rvs.php
which is a custom post type (called ‘rvs’) template. We use the get_children()
method to grab all the image attachments for the post, grab our image sources and finally inject them accordingly. In order to display the thumbnails portion we must duplicate the top slider markup so we can sync both sections as documented by Flexslider. Now we can grab the “full” size image for the main slider (large single images) and for the carousel (smaller thumbnail images) we retrieve the “medium” size. This is one of the benefits of using WordPress’ Media Uploader as it will generate different sizes for each image uploaded. Using this approach we can use smaller files for the thumbnails and larger images for the main showcase slides. Makes sense right?
<section class="rv-media">
<?php
$images =& get_children( array (
'post_parent' => $post->ID,
'post_type' => 'attachment',
'post_mime_type' => 'image'
));
if ( ! empty($images) ) {
// slider
echo '<div id="slider" class="flexslider"><ul class="slides">';
foreach ( $images as $attachment_id => $attachment ) {
$image_attributes = wp_get_attachment_image_src( $attachment_id, 'full' );
echo '<li><img src="//placehold.it/600x300/fff/111&text=Loading..." data-src="';
echo $image_attributes[0];
echo '" class="lazy" alt=""></li>';
}
echo '</ul></div>';
// carousel
echo '<div id="carousel" class="flexslider"><ul class="slides">';
foreach ( $images as $attachment_id => $attachment ) {
$image_attributes = wp_get_attachment_image_src( $attachment_id, 'medium' );
echo '<li><img src="//placehold.it/300x250/fff/111&text=Loading..." data-src="';
echo $image_attributes[0];
echo '" class="lazy" alt=""></li>';
}
echo '</ul></div>';
}
?>
</section>
single-rvs.php
templateLazy Loading Media
In the bottom of our document (just before the closing body tag) we load the Flexslider library followed by the custom config. The actual call for the entire config is wrapped in a window.load
event so we can make sure the DOM is loaded as quickly as possible and not blocking page load. This way we create a perceived performance improvement for users by loading only a few images at once and lazily loading the rest after the window load event occurs.
<?php if ( get_post_type() == 'rvs' ) : ?>
<script src="<?php echo get_template_directory_uri(); ?>/js/jquery.flexslider.min.js?v2.2.2" defer></script>
<script src="<?php echo get_template_directory_uri(); ?>/js/flexslider-config.js"></script>
<?php endif; ?>
Within our config we call window.load
and then a call to the Flexslider using some keys given to us by the Flexslider API and of course set our options accordingly. The following will only load the first two main gallery images at full size and finally load the first 3 thumbnails as medium image attachments lazily. Each time a slide advances it loads the next slide image in the series. This way we pre-load ahead of time and make the experience that much faster for the user.
function initSlides(slider) { // Fires when the slider loads the first slide
var slide_count = slider.count - 1;
jQuery(slider)
.find('img.lazy:eq(0), img.lazy:eq(1)')
.each(function() {
var src = jQuery(this).attr('data-src');
jQuery(this).attr('src', src).removeAttr('data-src');
});
}
function initCarSlides(slider) { // Fires when the slider loads the first slide
var amt = slider.count,
car_count = jQuery(slider).find("img.lazy").slice(0, 4);
car_count.each(function () {
var src = jQuery(this).attr("data-src");
jQuery(this).attr("src", src).removeAttr("data-src").removeClass("lazy");
});
}
function loadSlides(slider) { // Fires asynchronously with each slider animation
var slides = slider.slides,
index = slider.animatingTo,
$slide = jQuery(slides[index]),
$img = $slide.find('img[data-src]'),
current = index,
nxt_slide = current + 1,
prev_slide = current - 1;
$slide
.parent()
.find('img.lazy:eq(' current '), img.lazy:eq(' prev_slide '), img.lazy:eq(' nxt_slide ')')
.each(function() {
var src = jQuery(this).attr('data-src');
jQuery(this).attr('src', src).removeAttr('data-src');
});
}
jQuery(window).load(function() {
// Since we're syncing the carousel it req. init first
jQuery('#carousel').flexslider({
animation: "slide",
controlNav: false,
animationLoop: false,
slideshow: false,
itemWidth: 200,
asNavFor: '#slider',
move: 4,
// Fires when the slider loads the first slide
start: function(slider) {
initCarSlides(slider);
},
// Fires asynchronously with each slider animation
before: function(slider) {
initCarSlides(slider);
}
});
jQuery('#slider').flexslider({
animation: "fade",
touch: true,
slideshow: false,
controlNav: false,
sync: "#carousel",
slideshowSpeed: 7000,
animationSpeed: 600,
initDelay: 0,
// Fires when the slider loads the first slide
start: function(slider) {
initSlides(slider);
},
// Fires asynchronously with each slider animation
before: function(slider) {
loadSlides(slider);
}
});
});
The final product
The following is a screenshot of my final prototype sent over for approval. As you can see, we grab all the posts attachments and inject them into our slider (lazily of course).

Fantastic way of getting lazy load to work with Flexslider! Thanks for sharing!
NP Chuck! I hope it comes in helpful. Cheers!