From 1766e37a6358d2abe03ec5695279f1b6c860e522 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Mon, 13 May 2019 10:55:29 +0200 Subject: [PATCH] iframe background preload behavior now matches inline iframes + adheres to the new 'preloadIframes' config option --- README.md | 2 + js/reveal.js | 35 ++++++---- test/test-iframe-backgrounds.html | 104 ++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 11 deletions(-) create mode 100644 test/test-iframe-backgrounds.html diff --git a/README.md b/README.md index 65f93329..7bd33c64 100644 --- a/README.md +++ b/README.md @@ -778,6 +778,8 @@ Embeds a web page as a slide background that covers 100% of the reveal.js width ``` +Iframes are lazy-loaded when they become visible. If you'd like to preload iframes aehad of time, you can append a `data-preload` attribute to the slide `
`. You can also enable preloading globally for all iframes using the `preloadIframes` configuration option. + #### Background Transitions Backgrounds transition using a fade animation by default. This can be changed to a linear sliding transition by passing `backgroundTransition: 'slide'` to the `Reveal.initialize()` call. Alternatively you can set `data-background-transition` on any section with a background to override that specific transition. diff --git a/js/reveal.js b/js/reveal.js index 91e73962..cd51ccac 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -1217,6 +1217,8 @@ if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor; if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition ); + if( slide.hasAttribute( 'data-preload' ) ) element.setAttribute( 'data-preload', '' ); + // Background image options are set on the content wrapper if( data.backgroundSize ) contentElement.style.backgroundSize = data.backgroundSize; if( data.backgroundRepeat ) contentElement.style.backgroundRepeat = data.backgroundRepeat; @@ -3625,7 +3627,7 @@ // Stop content inside of previous backgrounds if( previousBackground ) { - stopEmbeddedContent( previousBackground ); + stopEmbeddedContent( previousBackground, { unloadIframes: !shouldPreload( previousBackground ) } ); } @@ -3804,6 +3806,7 @@ background.style.display = 'block'; var backgroundContent = slide.slideBackgroundContentElement; + var backgroundIframe = slide.getAttribute( 'data-background-iframe' ); // If the background contains media, load it if( background.hasAttribute( 'data-loaded' ) === false ) { @@ -3812,8 +3815,7 @@ var backgroundImage = slide.getAttribute( 'data-background-image' ), backgroundVideo = slide.getAttribute( 'data-background-video' ), backgroundVideoLoop = slide.hasAttribute( 'data-background-video-loop' ), - backgroundVideoMuted = slide.hasAttribute( 'data-background-video-muted' ), - backgroundIframe = slide.getAttribute( 'data-background-iframe' ); + backgroundVideoMuted = slide.hasAttribute( 'data-background-video-muted' ); // Images if( backgroundImage ) { @@ -3854,14 +3856,7 @@ iframe.setAttribute( 'mozallowfullscreen', '' ); iframe.setAttribute( 'webkitallowfullscreen', '' ); - // Only load autoplaying content when the slide is shown to - // avoid having it play in the background - if( /autoplay=(1|true|yes)/gi.test( backgroundIframe ) ) { - iframe.setAttribute( 'data-src', backgroundIframe ); - } - else { - iframe.setAttribute( 'src', backgroundIframe ); - } + iframe.setAttribute( 'data-src', backgroundIframe ); iframe.style.width = '100%'; iframe.style.height = '100%'; @@ -3872,6 +3867,19 @@ } } + // Start loading preloadable iframes + var backgroundIframeElement = backgroundContent.querySelector( 'iframe[data-src]' ); + if( backgroundIframeElement ) { + + // Check if this iframe is eligible to be preloaded + if( shouldPreload( background ) && !/autoplay=(1|true|yes)/gi.test( backgroundIframe ) ) { + if( backgroundIframeElement.getAttribute( 'src' ) !== backgroundIframe ) { + backgroundIframeElement.setAttribute( 'src', backgroundIframe ); + } + } + + } + } } @@ -3891,6 +3899,11 @@ var background = getSlideBackground( slide ); if( background ) { background.style.display = 'none'; + + // Unload any background iframes + toArray( background.querySelectorAll( 'iframe[src]' ) ).forEach( function( element ) { + element.removeAttribute( 'src' ); + } ); } // Reset lazy-loaded media elements with src attributes diff --git a/test/test-iframe-backgrounds.html b/test/test-iframe-backgrounds.html new file mode 100644 index 00000000..15888bcb --- /dev/null +++ b/test/test-iframe-backgrounds.html @@ -0,0 +1,104 @@ + + + + + + + reveal.js - Test Iframe Backgrounds + + + + + + + +
+
+ + + + + + + + + +