2

So I'm building a website that will use a lot of animated GIF's on mouse hover. There will be a lot of images, and I only want to load the images that will be used on any given page. It's using WordPress so I can use the conditional tags to only put out the URL's of the images I need on a certain page.

My problem was how to tell the browser/server which images needed to be preloaded. I decided to add a HTML5 data attribute to the containing element.

For example, I would have a DIV with this PHP in it:

<div id="home-container" class="preload" data-preload="<?php echo preloadImages(); ?>"></div>

Which would call this function in PHP:

function preloadImages() {
    global $post;
    $templateURL = get_template_directory_uri();
    $images = array();

    if( is_page('test') )
        $images[] = "'".$templateURL."/images/gifs-static/button-info-tab-close-off.gif'";
        $images[] = "'".$templateURL."/images/gifs-animated/button-info-tab-close.gif'";
    }

    return implode(", ", $images);
}

So the output would be this:

<div id="home-container" class="preload" data-preload="'http://example.com/images/gifs-static/button-info-tab-close-off.gif', 'http://example.com/images/gifs-animated/button-info-tab-close.gif'"></div>

And then I run this JavaScript:

jQuery('.preload').each(function(){

        var images = [
            // Comma separated list
            jQuery(this).data('preload')
        ];

        jQuery(images).each(function() {
            jQuery('<img />').attr('src', this).addClass('preloaded').appendTo('body').hide();
        });
});

The problem is that the JavaScript does not like the comma separated list. If I just write in the URLs, it works fine. So is there a better way to pass in those URLs? Or a better way in general?

3 Answers 3

3

You need to split the string of URLs by the deliminator commas into an array:

    var images = jQuery(this).data('preload').split(',');

jQuery(this).data('preload') is returning a string, and you can use .split() to split that string into an array: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/Split

Also you can make your loop run a little faster by using $.each():

jQuery('.preload').each(function(){

        var images = [
            // Comma seperated list
            jQuery(this).data('preload')
        ];

        jQuery.each(images, function() {
            jQuery('<img />').attr('src', this).addClass('preloaded').appendTo('body').hide();
        });
});

Note that you shouldn't have anything other than the commas that separate the different urls in the data-attribute:

<div id="home-container" class="preload" data-preload="http://example.com/images/gifs-static/button-info-tab-close-off.gif,http://example.com/images/gifs-animated/button-info-tab-close.gif"></div>
Sign up to request clarification or add additional context in comments.

Comments

1

Why don't you put the list directly in a Js array ?

Something like :

<script>
    var aPreloadImages = <?php echo preloadImages(); ?>;

    for (index in aPreloadImages) {
        jQuery('<img />').attr('src', aPreloadImages[index]).addClass('preloaded').appendTo('body').hide();
    }
</script>

And your PHP code :

function preloadImages() {
    global $post;
    $templateURL = get_template_directory_uri();
    $images = array();

    if( is_page('test') )
        $images[] = "'".$templateURL."/images/gifs-static/button-info-tab-close-off.gif'";
        $images[] = "'".$templateURL."/images/gifs-animated/button-info-tab-close.gif'";
    }

    return json_encode($images);
}

4 Comments

I was trying to keep my JS separate from my HTML. Is there a way to keep it separate?
Well then I think the answer from @Jasper is better appropriate for your need.
This is definitely the most straightforward approach. Writing to HTML, rendering, then reading from the DOM is two stages more indirect. +1 @cx42net.
@Drew Baker This IS the way to keep it separate!
1

Make your php return the data to the element as an actual array, wrapped in []. Then, when you pull it from the data attribute using the .data() method, jquery will convert it into a real array.

div

<div class="preload" data-preload='["foo.jpg","bar.jpg","foobar.gif","barfoo.png"]'></div>

code

var images = jQuery(this).data('preload');

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.