Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Responsive Background Images - The JavaScript
<?php
if ( has_post_thumbnail() ) {
$img_id = get_post_thumbnail_id( $post->ID );
$img_settings = array(
array(
'size' => 'featured-image-mobile',
'breakpoint' => '480',
),
array(
'size' => 'featured-image-tablet',
'breakpoint' => '768',
),
array(
'size' => 'featured-image-desktop',
'breakpoint' => '1024',
),
);
?>
<div
class="js-bg-img my-example-element"
<?php
responsive_bg_image_attrs(
$img_id,
$img_settings,
'featured-image-desktop'
);
?>
>
<h1>Example Heading</h1>
</div>
<?php
}
(function($) {
'use strict';
// Function to change the background
// image of an element or collection of
// elements at different breakpoints
// based on image urls stored in data
// attributes.
//
// This function is added as a property
// of the window object, and as such is
// now available globally (see below).
// -------------------------------------
window.responsiveBackgroundImages = function( selector ) {
// Abort if Modernizr is not available.
// -------------------------------------
if ( typeof Modernizr === 'undefined' ) {
return;
}
// Abort if we have no selector.
// -------------------------------------
if ( ! selector ) {
return;
}
// Store the jQuery object containing a
// list of elements matching our chosen
// CSS selector.
// -------------------------------------
var $bg_img_el = $( selector );
// Iterate over all elements that have
// the chosen selector.
// -------------------------------------
$bg_img_el.each( function( index, element ) {
// Set-up our variables.
// -------------------------------------
var css_prop = 'background-image',
$img_target = $(element),
img_data = [],
img_default_src = '',
// Gets the URL from the background-image property.
img_current_src = $(element)
.css( css_prop )
.replace ( "url(", "" )
.replace( ")", "")
.replace( /\"/gi, "" );
// Get all of the element attributes.
// -------------------------------------
$.each( this.attributes, function( index, element ) {
// Get and store the default image.
// -------------------------------------
if ( this.name.indexOf( 'data-default-bg' ) !== -1 ) {
img_default_src = this.value || '';
}
// Get and store the breakpoint and the
// image src as an object in our array
// of image data.
// -------------------------------------
if ( this.name.indexOf( 'data-bg-' ) !== -1 ) {
// Regex to extract the breakpoint value
// from the attribute name.
// -------------------------------------
var regex = /data-bg-(\d*)/i,
match = this.name.match( regex );
// Make sure we only add the the image
// data if the URL is present and we
// have a match.
// -------------------------------------
if (
this.value !== '' &&
typeof this.value !== 'undefined' &&
typeof match[1] !== 'undefined'
) {
var data = {
breakpoint: parseInt( match[1] ),
src: this.value,
};
img_data.push( data );
}
}
});
// Iterate over our data object and
// replace the background image with the
// most appropriate version for the
// current viewport size if required.
// -------------------------------------
for ( var i = 0; i < img_data.length; i++ ) {
// Set-up our variables.
// -------------------------------------
var src = img_data[ i ].src,
next = i+1,
// Ensure the first breakpoint value is always zero.
bp_min = i === 0 ? 0 : img_data[ i ].breakpoint,
// Ensure the last breakpoint value is always high.
bp_max = i === img_data.length - 1 ? 9999 : img_data[ next ].breakpoint -1;
// Carry out a Modernzir media query
// check for each breakpoint defined in
// our array, and update the background
// image CSS property for the element.
// -------------------------------------
if ( Modernizr.mq( 'screen and ( min-width: ' + bp_min + 'px ) and ( max-width: ' + bp_max + 'px )' ) ) {
// Only update the background image if
// the image for this breakpoint is not
// the same as the existing image.
// -------------------------------------
if ( img_current_src !== src ) {
$img_target.css( css_prop, 'url("' + src + '")' );
}
}
};
// Use the default image as a fallback
// if this element still does not have a
// background image set, for whatever
// reason that may be.
// -------------------------------------
var bg_img = $img_target
.css( css_prop )
.replace ( "url(", "" )
.replace( ")", "")
.replace( /\"/gi, "" );
if (
bg_img === 'none' &&
img_default_src !== ''
) {
$img_target.css( css_prop, 'url("' + img_default_src + '")' );
}
});
}
// Invoke on page load.
//
// Pass in a CSS selector representing
// an element or group of elements.
// -------------------------------------
window.responsiveBackgroundImages( '.js-bg-img' );
// Invoke for the browser window resize
// and orientation change events, with a
// throttle for better performance.
// -------------------------------------
var resizeTimer = '';
$( window ).on( "resize orientationchange", function( event ) {
clearTimeout( resizeTimer );
resizeTimer = setTimeout( function() {
// Pass in a CSS selector representing
// an element or group of elements.
// -------------------------------------
window.responsiveBackgroundImages( '.js-bg-img' );
}, 300 );
});
})( jQuery );
<?php
/**
* Responsive background image attributes
*
* Example `$img_settings` array...
*
* ```php
* $settings = array(
* array(
* 'size' => 'featured-image-mobile',
* 'breakpoint' => '480',
* ),
* array(
* 'size' => 'featured-image-tablet',
* 'breakpoint' => '768',
* ),
* array(
* 'size' => 'featured-image-desktop',
* 'breakpoint' => '1024',
* ),
* );
* ```
*
* @param int $img_id Post ID of the image attachment.
* @param array $img_settings Array of image sizes and breakpoints.
* @param string $default_img_size Slug name of the default size to be used.
* @param bool $return Whether to echo or return the attributes.
*/
function responsive_bg_image_attrs( $img_id, $img_settings, $default_img_size, $echo = true ) {
// Return if the ID is empty.
if ( empty( $img_id ) ) {
return;
}
// Handle a string being passed in.
$img_id = intval( $img_id );
// Is this a valid image?
$status = get_post_status( $img_id );
// Only proceed if the image has a published status,
// an array of settings and a default image size.
if ( empty( $status ) || empty( $img_settings ) || empty( $default_img_size ) )
return;
}
$data_attributes = '';
// Loop through the image settings.
foreach ( $img_settings as $key => $setting ) {
// Get the size.
$img_size = ( isset( $setting['size'] ) ) ? $setting['size'] : '';
$img_breakpoint = ( isset( $setting['breakpoint'] ) ) ? $setting['breakpoint'] : '';
// Check both values are valid.
if ( ! empty( $img_size ) && ! empty( $img_breakpoint ) ) {
// Feth the image src and retrieve the URL.
$img_src = wp_get_attachment_image_src( $img_id, $img_size );
$img_url = ( ! empty( $img_src ) ) ? $img_src[0] : '';
// Add the attribute if we have the image URL.
if ( ! empty( $img_url ) ) {
$data_attributes .= 'data-bg-' . esc_attr( $img_breakpoint ) . '="' . esc_url( $img_url ) . '" '; // Must be a space at the end!.
}
}
}
// Feth the default image src and retrieve the URL.
$default_img_src = wp_get_attachment_image_src( $img_id, $default_img_size );
$default_img_url = ( ! empty( $default_img_src ) ) ? $default_img_src[0] : '';
// Add the default image attribute if we have the image URL.
if ( ! empty( $default_img_src ) ) {
$data_attributes .= 'data-default-bg="' . esc_url( $default_img_url ) . '" ';
}
// Either return or echo the attributes.
if ( $echo ) {
echo $data_attributes;
} else {
return $data_attributes;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment