con con - 3 months ago 39
Ajax Question

Add/Remove Slides from Reveal.JS dynamically

Is it possible to add/remove slides while a presentation is running with reveal.js? To be precise, is there an API for that or maybe some dirty workaround?

Answer

I was curious about this as well for an upcoming project; looked around and couldn't find anything so I wrote something for my own project, appended at the end. Adding a slide after your current slide is pretty straightforward. Just append a section element to '.slides', and make sure the section has class 'future'. Also, if you are on the last slide, you need to add class 'enabled' to '.navigate-right'. Adding something before the current slide messes up the numbering, so you need to add it with class 'past', and then move to the next slide.

Same would go for removing a slide, if you remove a '.past' slide, that messes up your numbering. I haven't tested my code well (yet), so if you use it as is test well.

        Reveal.addEventListener( 'ready', function( event ) {
            Reveal.add = function( content = '',index = -1 ){ 
                dom = {},

                dom.slides = document.querySelector( '.reveal .slides' );
                var newSlide = document.createElement( 'section' );
                if( index === -1 ) { //adding slide to end
                    newSlide.classList.add( 'future' );
                    dom.slides.appendChild(newSlide);
                    document.querySelector( '.navigate-right' ).classList.add( 'enabled' ); //just enable it, even if it is
                } else if( index > Reveal.getIndices().h ) {
                    newSlide.classList.add( 'future' );
                    dom.slides.insertBefore(newSlide,dom.slides.querySelectorAll('section:nth-child('+(index+1)+')')[0]);
                } else if( index <= Reveal.getIndices().h ) {
                    newSlide.classList.add( 'past' );
                    dom.slides.insertBefore(newSlide,dom.slides.querySelectorAll('section:nth-child('+(index+1)+')')[0]);
                    Reveal.next();
                }
                newSlide.innerHTML = content;
            };
            Reveal.remove = function( index = -1 ){ 
                dom = {},

                dom.wrapper = document.querySelector( '.reveal' );
                dom.slides = document.querySelector( '.reveal .slides' );
                var target = (dom.wrapper.querySelectorAll('.slides > section:nth-child('+(index+1)+')')[0]) ? dom.wrapper.querySelectorAll('.slides > section:nth-child('+(index+1)+')')[0] : false;

                if( index === -1 ) {
                    if (Reveal.isLastSlide()) Reveal.prev();
                    dom.slides.removeChild(dom.wrapper.querySelectorAll('.slides > section')[dom.wrapper.querySelectorAll('.slides > section').length-1]);
                    if (Reveal.isLastSlide()) document.querySelector( '.navigate-right' ).classList.remove( 'enabled' );
                } else if( index > Reveal.getIndices().h && target ) {
                    dom.slides.removeChild(target);
                    if (Reveal.getIndices().h == dom.wrapper.querySelectorAll('.slides > section').length-1) document.querySelector( '.navigate-right' ).classList.remove( 'enabled' );
                } else if( index < Reveal.getIndices().h && target ) {
                    dom.slides.removeChild(target);
                    location.hash = '/'+parseInt(Reveal.getIndices().h-1);
                } else if( index == Reveal.getIndices().h && target ) {
                    if (index == 0) {
                        Reveal.next();
                        document.querySelector( '.navigate-left' ).classList.remove( 'enabled' );
                    } else Reveal.prev();
                    dom.slides.removeChild(target);
                    if( dom.wrapper.querySelectorAll('.slides > section').length == index) document.querySelector( '.navigate-right' ).classList.remove( 'enabled' );
                }
            };
        } );

If you want to use this, add it after Reveal.initialize({...});

Call it with Reveal.add(content,index), or Reveal.remove(index).

Reveal.add('<h3>Slide title</h3>') 

would add that as the last slide,

Reveal.add('<h3>Slide title</h3>',0) 

at the beginning.

Reveal.add('<h3>Slide title</h3>',3) 

would add it in the 3rd location.

Reveal.remove() removes the last slide, Reveal.remove(n) any other (if it exists).

Comments