Last active
May 5, 2022 20:48
-
-
Save ithinkandicode/1061ba9574c014a8ed4164eb7bbb3a90 to your computer and use it in GitHub Desktop.
Responsive BG
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Responsive Background Image (ES5) | |
* | |
* Uses an invisible <picture> element with srcset to change the parent | |
* container's background image | |
* | |
* https://gist.github.com/ithinkandicode/1061ba9574c014a8ed4164eb7bbb3a90 | |
* | |
* @version ES5-1.0.1 | |
*/ | |
/* | |
Example: | |
<div style="background-image: url('mobile-size.jpg')" data-responsive-bg> | |
<div class="visibility-hidden"> | |
<picture> | |
<source media="(min-width: 1280px)" srcset="xl-size.jpg"> | |
<source media="(min-width: 992px) and (max-width: 1199px)" srcset="lg-size.jpg"> | |
<source media="(min-width: 768px) and (max-width: 991px)" srcset="md-size.jpg"> | |
<source media="(min-width: 576px) and (max-width: 767px)" srcset="sm-size.jpg"> | |
<img src="mobile-size.jpg" alt=""> | |
</picture> | |
</div> | |
</div> | |
*/ | |
// IIFE | |
(function() | |
{ | |
// ES5 pesudo-class | |
var RSPBG = { | |
init: function() | |
{ | |
var self = this; | |
var $rspBgs = $( '[data-responsive-bg]' ); | |
$rspBgs.each( function( i, element ) | |
{ | |
var $el = $( element ); | |
try | |
{ | |
var img = $el.find( 'img' )[0]; | |
// Store current src in element's data | |
// Updated in main() | |
$el.data( 'bgsrc', '' ); | |
// Ensure all is valid | |
self.validateElements( img, $el ); | |
// If validation passed, proceed | |
self.main( img, $el ); | |
} | |
catch( err ) | |
{ | |
console.error( '[ResponsiveBG] ' + err.message, $el ); | |
return; | |
} | |
}); | |
}, | |
main: function( img, $el ) | |
{ | |
// Triggered when the browser loads in a new source image | |
$( img ).on( 'load', () => this.updateBg( img, $el ) ); | |
// If image was already loaded, update BG immediately | |
if( img.complete ) | |
{ | |
this.updateBg( img, $el ); | |
} | |
}, | |
updateBg: function( img, $el ) | |
{ | |
// Get current src | |
var currentSrc = ( typeof img.currentSrc !== 'undefined' ) ? img.currentSrc : img.src; | |
if ( $el.data( 'bgsrc' ) !== currentSrc ) | |
{ | |
// Image src has changed since we last checked, so update the BG img | |
$el.data( 'bgsrc', currentSrc ); | |
$el.css( 'background-image', 'url("' + currentSrc + '")' ); | |
} | |
}, | |
/** | |
* Check container's elements to ensure they're valid | |
* | |
* Throws errors if validaiton fails. Errors must be caught in calling function | |
*/ | |
validateElements: function( img, $el ) | |
{ | |
if ( !img ) | |
{ | |
throw new Error( 'Responsive BG container must contain an <img> element' ); | |
} | |
if ( img.src === '' ) | |
{ | |
throw new Error( 'Responsive BG container contains an image with an empty src attribute' ); | |
} | |
const isPicture = ( $el[0].tagName === 'PICTURE' ); | |
const hasPicture = ( $el.find( 'picture' ).length ); | |
const hasSource = ( $el.find( 'source' ).length ); | |
if ( !(isPicture || hasPicture) ) | |
{ | |
throw new Error( 'Responsive BG container must contain a <picture> element' ); | |
} | |
if ( !hasSource ) | |
{ | |
throw new Error( 'Responsive BG container must contain a <source> element' ); | |
} | |
} | |
}; | |
// Auto-init | |
$( document ).ready(function() | |
{ | |
RSPBG.init(); | |
}); | |
})(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Responsive Background Image | |
* | |
* Uses an invisible <picture> element with srcset to change the parent | |
* container's background image | |
* | |
* https://gist.github.com/ithinkandicode/1061ba9574c014a8ed4164eb7bbb3a90 | |
* @version ES6-1.0.0 | |
*/ | |
/* | |
Example: | |
<div style="background-image: url('mobile-size.jpg')" data-responsive-bg> | |
<div class="visibility-hidden"> | |
<picture> | |
<source media="(min-width: 1280px)" srcset="xl-size.jpg"> | |
<source media="(min-width: 992px) and (max-width: 1199px)" srcset="lg-size.jpg"> | |
<source media="(min-width: 768px) and (max-width: 991px)" srcset="md-size.jpg"> | |
<source media="(min-width: 576px) and (max-width: 767px)" srcset="sm-size.jpg"> | |
<img src="mobile-size.jpg" alt=""> | |
</picture> | |
</div> | |
</div> | |
*/ | |
/** | |
* Component Init: Responsive Background Image | |
* | |
* @return {void} | |
*/ | |
function init() | |
{ | |
const $rspBgs = $( '[data-responsive-bg]' ); | |
$rspBgs.each( ( i, element ) => | |
{ | |
const $el = $( element ); | |
try | |
{ | |
const img = $el.find( 'img' )[0]; | |
// Store current src in element's data | |
// Updated in main() | |
$el.data( 'bgsrc', '' ); | |
validateElements( img, $el ); | |
// If validation passed, proceed | |
main( img, $el ); | |
} | |
catch( err ) | |
{ | |
console.error( `[ResponsiveBG] ${err.message}`, $el ); | |
return; | |
} | |
}); | |
} | |
function main( img, $el ) | |
{ | |
// Triggered when the browser loads in a new source image | |
$( img ).on( 'load', () => updateBg( img, $el ) ); | |
// If image was already loaded, update BG immediately | |
if( img.complete ) | |
{ | |
updateBg( img, $el ); | |
} | |
} | |
function updateBg( img, $el ) | |
{ | |
// Get current src | |
let currentSrc = ( typeof img.currentSrc !== 'undefined' ) ? img.currentSrc : img.src; | |
if ( $el.data( 'bgsrc' ) !== currentSrc ) | |
{ | |
// Image src has changed since we last checked, so update the BG img | |
$el.data( 'bgsrc', currentSrc ); | |
$el.css( 'background-image', `url("${currentSrc}")` ); | |
} | |
} | |
/** | |
* Check container's elements to ensure they're valid | |
* | |
* Throws errors if validaiton fails. Errors must be caught in calling function | |
*/ | |
function validateElements( img, $el ) | |
{ | |
if ( !img ) | |
{ | |
throw new Error( 'Responsive BG container must contain an <img> element' ); | |
} | |
if ( img.src === '' ) | |
{ | |
throw new Error( 'Responsive BG container contains an image with an empty src attribute' ); | |
} | |
const isPicture = ( $el[0].tagName === 'PICTURE' ); | |
const hasPicture = ( $el.find( 'picture' ).length ); | |
const hasSource = ( $el.find( 'source' ).length ); | |
if ( !(isPicture || hasPicture) ) | |
{ | |
throw new Error( 'Responsive BG container must contain a <picture> element' ); | |
} | |
if ( !hasSource ) | |
{ | |
throw new Error( 'Responsive BG container must contain a <source> element' ); | |
} | |
} | |
export const ResponsiveBG = { init }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment