lazy-load iframes only for current slide, unload when hidden
This commit is contained in:
parent
152271efb2
commit
7dd33f188f
|
@ -317,7 +317,7 @@ Reveal.configure({
|
||||||
|
|
||||||
When working on presentation with a lot of media or iframe content it's important to load lazily. Lazy loading means that reveal.js will only load content for the few slides nearest to the current slide. The number of slides that are preloaded is determined by the `viewDistance` configuration option.
|
When working on presentation with a lot of media or iframe content it's important to load lazily. Lazy loading means that reveal.js will only load content for the few slides nearest to the current slide. The number of slides that are preloaded is determined by the `viewDistance` configuration option.
|
||||||
|
|
||||||
To enable lazy loading all you need to do is change your "src" attributes to "data-src" as shown below. This is supported for image, video, audio and iframe elements.
|
To enable lazy loading all you need to do is change your "src" attributes to "data-src" as shown below. This is supported for image, video, audio and iframe elements. Lazy loaded iframes will also unload when the containing slide is no longer visible.
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<section>
|
<section>
|
||||||
|
|
24
js/reveal.js
24
js/reveal.js
|
@ -2723,7 +2723,7 @@
|
||||||
slide.style.display = 'block';
|
slide.style.display = 'block';
|
||||||
|
|
||||||
// Media elements with data-src attributes
|
// Media elements with data-src attributes
|
||||||
toArray( slide.querySelectorAll( 'img[data-src], video[data-src], audio[data-src], iframe[data-src]' ) ).forEach( function( element ) {
|
toArray( slide.querySelectorAll( 'img[data-src]', 'video[data-src]', 'audio[data-src]' ) ).forEach( function( element ) {
|
||||||
element.setAttribute( 'src', element.getAttribute( 'data-src' ) );
|
element.setAttribute( 'src', element.getAttribute( 'data-src' ) );
|
||||||
element.removeAttribute( 'data-src' );
|
element.removeAttribute( 'data-src' );
|
||||||
} );
|
} );
|
||||||
|
@ -2909,19 +2909,24 @@
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// iframe embeds
|
// Lazy loading iframes
|
||||||
|
toArray( slide.querySelectorAll( 'iframe[data-src]' ) ).forEach( function( element ) {
|
||||||
|
element.setAttribute( 'src', element.getAttribute( 'data-src' ) );
|
||||||
|
} );
|
||||||
|
|
||||||
|
// Generic postMessage API for non-lazy loaded iframes
|
||||||
toArray( slide.querySelectorAll( 'iframe' ) ).forEach( function( el ) {
|
toArray( slide.querySelectorAll( 'iframe' ) ).forEach( function( el ) {
|
||||||
el.contentWindow.postMessage( 'slide:start', '*' );
|
el.contentWindow.postMessage( 'slide:start', '*' );
|
||||||
});
|
});
|
||||||
|
|
||||||
// YouTube embeds
|
// YouTube postMessage API
|
||||||
toArray( slide.querySelectorAll( 'iframe[src*="youtube.com/embed/"]' ) ).forEach( function( el ) {
|
toArray( slide.querySelectorAll( 'iframe[src*="youtube.com/embed/"]' ) ).forEach( function( el ) {
|
||||||
if( el.hasAttribute( 'data-autoplay' ) ) {
|
if( el.hasAttribute( 'data-autoplay' ) ) {
|
||||||
el.contentWindow.postMessage( '{"event":"command","func":"playVideo","args":""}', '*' );
|
el.contentWindow.postMessage( '{"event":"command","func":"playVideo","args":""}', '*' );
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Vimeo embeds
|
// Vimeo postMessage API
|
||||||
toArray( slide.querySelectorAll( 'iframe[src*="player.vimeo.com/"]' ) ).forEach( function( el ) {
|
toArray( slide.querySelectorAll( 'iframe[src*="player.vimeo.com/"]' ) ).forEach( function( el ) {
|
||||||
if( el.hasAttribute( 'data-autoplay' ) ) {
|
if( el.hasAttribute( 'data-autoplay' ) ) {
|
||||||
el.contentWindow.postMessage( '{"method":"play"}', '*' );
|
el.contentWindow.postMessage( '{"method":"play"}', '*' );
|
||||||
|
@ -2945,19 +2950,24 @@
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// iframe embeds
|
// Lazy loading iframes
|
||||||
|
toArray( slide.querySelectorAll( 'iframe[data-src]' ) ).forEach( function( element ) {
|
||||||
|
element.removeAttribute( 'src' );
|
||||||
|
} );
|
||||||
|
|
||||||
|
// Generic postMessage API for non-lazy loaded iframes
|
||||||
toArray( slide.querySelectorAll( 'iframe' ) ).forEach( function( el ) {
|
toArray( slide.querySelectorAll( 'iframe' ) ).forEach( function( el ) {
|
||||||
el.contentWindow.postMessage( 'slide:stop', '*' );
|
el.contentWindow.postMessage( 'slide:stop', '*' );
|
||||||
});
|
});
|
||||||
|
|
||||||
// YouTube embeds
|
// YouTube postMessage API
|
||||||
toArray( slide.querySelectorAll( 'iframe[src*="youtube.com/embed/"]' ) ).forEach( function( el ) {
|
toArray( slide.querySelectorAll( 'iframe[src*="youtube.com/embed/"]' ) ).forEach( function( el ) {
|
||||||
if( !el.hasAttribute( 'data-ignore' ) && typeof el.contentWindow.postMessage === 'function' ) {
|
if( !el.hasAttribute( 'data-ignore' ) && typeof el.contentWindow.postMessage === 'function' ) {
|
||||||
el.contentWindow.postMessage( '{"event":"command","func":"pauseVideo","args":""}', '*' );
|
el.contentWindow.postMessage( '{"event":"command","func":"pauseVideo","args":""}', '*' );
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Vimeo embeds
|
// Vimeo postMessage API
|
||||||
toArray( slide.querySelectorAll( 'iframe[src*="player.vimeo.com/"]' ) ).forEach( function( el ) {
|
toArray( slide.querySelectorAll( 'iframe[src*="player.vimeo.com/"]' ) ).forEach( function( el ) {
|
||||||
if( !el.hasAttribute( 'data-ignore' ) && typeof el.contentWindow.postMessage === 'function' ) {
|
if( !el.hasAttribute( 'data-ignore' ) && typeof el.contentWindow.postMessage === 'function' ) {
|
||||||
el.contentWindow.postMessage( '{"method":"pause"}', '*' );
|
el.contentWindow.postMessage( '{"method":"pause"}', '*' );
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
<li class="fragment">4.2</li>
|
<li class="fragment">4.2</li>
|
||||||
<li class="fragment">4.3</li>
|
<li class="fragment">4.3</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<iframe data-src="http://example.com"></iframe>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
|
|
|
@ -495,6 +495,15 @@ Reveal.addEventListener( 'ready', function() {
|
||||||
strictEqual( document.querySelectorAll( '.reveal section img[src]' ).length, 1, 'Image source has been set' );
|
strictEqual( document.querySelectorAll( '.reveal section img[src]' ).length, 1, 'Image source has been set' );
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test( 'iframe with data-src', function() {
|
||||||
|
Reveal.slide( 0, 0 );
|
||||||
|
strictEqual( document.querySelectorAll( '.reveal section iframe[src]' ).length, 0, 'Iframe source is not set' );
|
||||||
|
Reveal.slide( 2, 0 );
|
||||||
|
strictEqual( document.querySelectorAll( '.reveal section iframe[src]' ).length, 1, 'Iframe source is set' );
|
||||||
|
Reveal.slide( 2, 1 );
|
||||||
|
strictEqual( document.querySelectorAll( '.reveal section iframe[src]' ).length, 0, 'Iframe source is not set' );
|
||||||
|
});
|
||||||
|
|
||||||
test( 'background images', function() {
|
test( 'background images', function() {
|
||||||
var imageSource1 = Reveal.getSlide( 0 ).getAttribute( 'data-background-image' );
|
var imageSource1 = Reveal.getSlide( 0 ).getAttribute( 'data-background-image' );
|
||||||
var imageSource2 = Reveal.getSlide( 1, 0 ).getAttribute( 'data-background' );
|
var imageSource2 = Reveal.getSlide( 1, 0 ).getAttribute( 'data-background' );
|
||||||
|
|
Loading…
Reference in New Issue