Royalslider and Picturefill.js

I’m creating a website which has the Royal Slider HTML version. I want to use picturefill to load the image optimized for the current resolution viewed. But I have problems getting it to work. It works while I serve the images via a normal WP_Query.

I’ve read this thread, but that did not help me, anybody an idea?

Read More

Thanks, /Paul

<div id="featuredAdv" class="royalSliderAdv rsMinW">

    <?php 

        $args_featured_adv = array(
            'posts_per_page' => -1,
            'orderby' => 'rand',
            'post_type' => 'advertenties',
            'meta_key' => 'advertentiepositie',
            'meta_value' => 'Featured'
        );

        $adv_featured = new WP_Query( $args_featured_adv );

        if( $adv_featured->have_posts() ): while ( $adv_featured->have_posts() ) : $adv_featured->the_post();

    ?>

    <a href="<?php the_field('link'); ?>" target="_blank" onClick="return recordOutboundLink(this, ['<?php the_title(); ?>', '<?php the_field('link'); ?>']);">

        <div class="rsContent">

                <?php

                    $attachment_id_ft = get_field('afbeelding');
                    $small_ft = wp_get_attachment_image_src( $attachment_id_ft, 'adv-b-small-small' ); // returns an array
                    $default_ft = wp_get_attachment_image_src( $attachment_id_ft, 'adv-b-small-default' ); // returns an array
                    $large_ft = wp_get_attachment_image_src( $attachment_id_ft, 'adv-b-small-large' ); // returns an array

                ?>

                <span data-picture data-alt="<?php the_title_attribute( array( 'before' => 'Photoq.nl: ', 'after' => '' ) ); ?>">
                    <span data-src="<?php echo $default_ft[0]; ?>"></span>
                    <span data-src="<?php echo $small_ft[0]; ?>" data-media="(min-width: 400px)"></span>
                    <span data-src="<?php echo $default_ft[0]; ?>" data-media="(min-width: 768px)"></span>
                    <span data-src="<?php echo $large_ft[0]; ?>" data-media="(min-width: 1200px)"></span>

                    <!-- Fallback content for non-JS browsers. Same img src as the initial, unqualified source element. -->
                    <noscript>
                        <img src="<?php echo $default_ft[0]; ?>" alt="">
                    </noscript>
                </span>

        </div>

    </a>

    <?php endwhile; endif; wp_reset_query(); ?>

</div> <!-- end #featuredAdv -->

<script>
    jQuery(document).ready(function($) {
        $('#featuredAdv').royalSlider({
            arrowsNav: false,
            loop: false,
            controlsInside: false,
            imageScaleMode: 'none',
            imageScalePadding: 0,
            arrowsNavAutoHide: false,
            autoScaleSlider: true,
            autoScaleSliderWidth: 270,
            autoScaleSliderHeight: 572,
            controlNavigation: 'bullets',
            numImagesToPreload: 1,
            thumbsFitInViewport: false,
            navigateByClick: true,
            startSlideId: 0,
            autoPlay: false,
            transitionType: 'move',
            globalCaption: true
        });
    });
</script>

edit: 28-06 09:40

Got in contact with developer… so he gave some tips. One of them was to make sure picturefill initializes before the slider. With that he means, at least I think, that picturefill.js needs to be loaded before the royalslider files.

Still no luck though. Oh en made a little change in the code due:

<div class="rsIMG">

does not follow the slider syntax.

Related posts

Leave a Reply

1 comment

  1. I managed to get RoyalSlider to work with Picturefill2 today, but you need to edit a section of the picturefill.js file to stop it recalculating on window resize. I just typed out some instructions in the RoyalSlider forum but I’ll copy here too in case it helps someone else.

    First up you have to grab picturefill.js from http://scottjehl.github.io/picturefill/#download .
    Then load up the script file in the HEAD of your document, not just before the body tag.
    If you require old browser support, i.e. browsers that don’t support HTML5 elements, you need to follow the instructions here to create a picture element. Alternatively, you can include Modernizr in your project (I was already using modernizr, so that’s how I did it).

    RoyalSlider Markup:
    Here is the code I used


    <div class="royalSlider rsDefault">
    <picture>
    <!--[if IE 9]><video style="display: none;"><![endif]-->
    <source srcset="img/gsa-01.jpg" media="(min-width: 768px)">
    <source srcset="img/gsa-01-smallest.jpg, img/gsa-01-smallest@2x.jpg 2x">
    <!--[if IE 9]></video><![endif]-->
    <img class="rsImg" srcset="img/gsa-01-smallest.jpg, img/gsa-01-smallest2x.jpg 2x" alt="GSA Est. 1935">
    </picture>
    <!-- etc... -->
    </div>

    It looks a bit of a mess at first but its pretty easy to understand, and it’s all explained at the picturefill webpage, but basically the first <source> element should always be the highest quality version of the image you pan to serve, specified with media queries for when it should be loaded. So in the example above at < 768px, gsa-01-smallest is loaded. If the device has a device pixel ratio > 1, then gsa-01-smallest2x.jpg is loaded, until finally if the device pixel ratio is 1, then gsa-01-smallest.jpg is loaded.
    The IE9 wrapper is just a trick for IE9 support.

    Now, in order to use RoyalSlider and picturefill together, you have to make sure that picturefill has ran through the page and added in the correct src attribute to the img tag, before you let RoyalSlider do it’s thing. In order to do this, place your usual code for royalslider (jQuery(document).ready(function($) {
    $(".royalSlider").royalSlider({...
    ) into a file called defer.js. Now, just before the final tag of your document, but obviously after the jQuery and Royalslider js script tags, use this code (known as a Google Defer js script):


    <script type="text/javascript">
    function downloadJSAtOnload() {
    var element = document.createElement("script");
    element.src = "js/defer.js";
    document.body.appendChild(element);
    }
    if (window.addEventListener)
    window.addEventListener("load", downloadJSAtOnload, false);
    else if (window.attachEvent)
    window.attachEvent("onload", downloadJSAtOnload);
    else window.onload = downloadJSAtOnload;
    </script>

    This says wait until the page has loaded everything else, then apply that script (loaded from js/defer.js).

    This works fantastically well, until you realise that when you resize the window everything breaks (FML!). This is because picturefill has a section of code in it that will make it swap out the image again every time the window is resized, which doesn’t work well with RoyalSlider at all. So, to stop this happening open up picturefill.js and find this block of code and comment it out (around line 250):


    if( w.addEventListener ){
    var resizeThrottle;
    w.addEventListener( "resize", function() {
    w.clearTimeout( resizeThrottle );
    resizeThrottle = w.setTimeout( function(){
    picturefill({ reevaluate: true });
    }, 60 );
    }, false );
    }

    This is how I got it to work, and its a fantastic way of serving a slider to a phone – especially a full width slider. I don’t have to load a ~400kb full width image on a 3G phone, I can serve an ~80kb image instead 🙂