aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Rothman <max@collegevine.com>2019-03-19 22:28:30 -0400
committerMax Rothman <max@collegevine.com>2019-03-22 10:45:08 -0400
commit93b1abc7364eacb028c30f145603d0a155f2fcbd (patch)
tree7eb0e9939d9d91f6bd462f7284338e0e8ef9e39b
parentc7db11d9cfeb7984f643af3effb1fea5865ce4cc (diff)
downloadfreenode-live-2017-presentation-93b1abc7364eacb028c30f145603d0a155f2fcbd.tar
freenode-live-2017-presentation-93b1abc7364eacb028c30f145603d0a155f2fcbd.tar.gz
Add data-preload attribute for iframes
Allows lazy-loaded (i.e. data-src) iframes to be preloaded when they come within the viewDistance, rather than once they're visible.
-rw-r--r--README.md21
-rw-r--r--js/reveal.js54
2 files changed, 68 insertions, 7 deletions
diff --git a/README.md b/README.md
index 4c720e2..20b07f9 100644
--- a/README.md
+++ b/README.md
@@ -316,6 +316,13 @@ Reveal.initialize({
// - false: No media will autoplay, regardless of individual setting
autoPlayMedia: null,
+ // Global override for preloading lazy-loaded iframes
+ // - null: Iframes with data-src AND data-preload will be loaded when within
+ // the viewDistance, iframes with only data-src will be loaded when visible
+ // - true: All iframes with data-src will be loaded when within the viewDistance
+ // - false: All iframes with data-src will be loaded only when visible
+ preloadIframes: null,
+
// Number of milliseconds between automatically proceeding to the
// next slide, disabled when set to 0, this value can be overwritten
// by using a data-autoslide attribute on your slides
@@ -555,10 +562,24 @@ To enable lazy loading all you need to do is change your `src` attributes to `da
```
#### Lazy Loading Iframes
+
Note that lazy loaded iframes ignore the `viewDistance` configuration and will only load when their containing slide becomes visible. Iframes are also unloaded as soon as the slide is hidden.
When we lazy load a video or audio element, reveal.js won't start playing that content until the slide becomes visible. However there is no way to control this for an iframe since that could contain any kind of content. That means if we loaded an iframe before the slide is visible on screen it could begin playing media and sound in the background.
+You can override this behavior with the `data-preload` attribute. The iframe below will be loaded
+according to the `viewDistance`.
+
+```html
+<section>
+ <iframe data-src="http://hakim.se" data-preload></iframe>
+</section>
+```
+
+You can also change the default globally with the `preloadIframes` configuration option. If set to
+`true` ALL iframes with a `data-src` attribute will be preloaded when within the `viewDistance`
+regardless of individual `data-preload` attributes. If set to `false`, all iframes will only be
+loaded when they become visible.
### API
diff --git a/js/reveal.js b/js/reveal.js
index 387077a..662679b 100644
--- a/js/reveal.js
+++ b/js/reveal.js
@@ -3672,6 +3672,26 @@
}
/**
+ * Should the given element be preloaded?
+ * Decides based on local element attributes and global config.
+ *
+ * @param {HTMLElement} element
+ */
+ function shouldPreload(element) {
+
+ // Prefer an explicit global preload setting
+ var preload = config.preloadIframes;
+
+ // If no global setting is available, fall back on the element's
+ // own preload setting
+ if( typeof preload !== 'boolean' ) {
+ preload = element.hasAttribute( 'data-preload' );
+ }
+
+ return preload;
+ }
+
+ /**
* Called when the given slide is within the configured view
* distance. Shows the slide element and loads any content
* that is set to load lazily (data-src).
@@ -3686,10 +3706,20 @@
slide.style.display = config.display;
// Media elements with data-src attributes
- toArray( slide.querySelectorAll( 'img[data-src], video[data-src], audio[data-src]' ) ).forEach( function( element ) {
- element.setAttribute( 'src', element.getAttribute( 'data-src' ) );
- element.setAttribute( 'data-lazy-loaded', '' );
- element.removeAttribute( 'data-src' );
+ toArray( slide.querySelectorAll( 'img[data-src], video[data-src], audio[data-src], iframe[data-src]' ) ).forEach( function( element ) {
+ var load = function( el ) {
+ el.setAttribute( 'src', el.getAttribute( 'data-src' ) );
+ el.setAttribute( 'data-lazy-loaded', '' );
+ el.removeAttribute( 'data-src' );
+ };
+
+ if( element.tagName === 'IFRAME') {
+ if( shouldPreload(element) ) {
+ load(element);
+ }
+ } else {
+ load(element);
+ }
} );
// Media elements with <source> children
@@ -3807,9 +3837,19 @@
}
// Reset lazy-loaded media elements with src attributes
- toArray( slide.querySelectorAll( 'video[data-lazy-loaded][src], audio[data-lazy-loaded][src]' ) ).forEach( function( element ) {
- element.setAttribute( 'data-src', element.getAttribute( 'src' ) );
- element.removeAttribute( 'src' );
+ toArray( slide.querySelectorAll( 'video[data-lazy-loaded][src], audio[data-lazy-loaded][src], iframe[data-lazy-loaded][src]' ) ).forEach( function( element ) {
+ var unload = function( el ) {
+ el.setAttribute( 'data-src', el.getAttribute( 'src' ) );
+ el.removeAttribute( 'src' );
+ };
+
+ if( element.tagName === 'IFRAME' ) {
+ if( shouldPreload(element) ) {
+ unload(element);
+ }
+ } else {
+ unload(element);
+ }
} );
// Reset lazy-loaded media elements with <source> children