add transitionend event and docs
This commit is contained in:
		
							
								
								
									
										46
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								README.md
									
									
									
									
									
								
							| @@ -28,7 +28,7 @@ This project was started and is maintained by [@hakimel](https://github.com/haki | |||||||
| - [Lazy Loading](#lazy-loading) | - [Lazy Loading](#lazy-loading) | ||||||
| - [API](#api) | - [API](#api) | ||||||
|   - [Custom Key Bindings](#custom-key-bindings) |   - [Custom Key Bindings](#custom-key-bindings) | ||||||
|   - [Slide Changed Event](#slide-changed-event) |   - [Slide Change Events](#slide-change-events) | ||||||
|   - [Presentation State](#presentation-state) |   - [Presentation State](#presentation-state) | ||||||
|   - [Slide States](#slide-states) |   - [Slide States](#slide-states) | ||||||
|   - [Slide Backgrounds](#slide-backgrounds) |   - [Slide Backgrounds](#slide-backgrounds) | ||||||
| @@ -458,8 +458,8 @@ Reveal.js doesn't _rely_ on any third party scripts to work but a few optional l | |||||||
| Reveal.initialize({ | Reveal.initialize({ | ||||||
|   dependencies: [ |   dependencies: [ | ||||||
|     // Interpret Markdown in <section> elements |     // Interpret Markdown in <section> elements | ||||||
|     { src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }, |     { src: 'plugin/markdown/marked.js', condition: () => { return !!document.querySelector( '[data-markdown]' ); } }, | ||||||
|     { src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }, |     { src: 'plugin/markdown/markdown.js', condition: () => { return !!document.querySelector( '[data-markdown]' ); } }, | ||||||
|  |  | ||||||
|     // Syntax highlight for <code> elements |     // Syntax highlight for <code> elements | ||||||
|     { src: 'plugin/highlight/highlight.js', async: true }, |     { src: 'plugin/highlight/highlight.js', async: true }, | ||||||
| @@ -490,7 +490,7 @@ You can also include dependencies which are bundled/already present on the page. | |||||||
| A `ready` event is fired when reveal.js has loaded all non-async dependencies and is ready to start navigating. To check if reveal.js is already 'ready' you can call `Reveal.isReady()`. | A `ready` event is fired when reveal.js has loaded all non-async dependencies and is ready to start navigating. To check if reveal.js is already 'ready' you can call `Reveal.isReady()`. | ||||||
|  |  | ||||||
| ```javascript | ```javascript | ||||||
| Reveal.on( 'ready', function( event ) { | Reveal.on( 'ready', event => { | ||||||
|   // event.currentSlide, event.indexh, event.indexv |   // event.currentSlide, event.indexh, event.indexv | ||||||
| } ); | } ); | ||||||
| ``` | ``` | ||||||
| @@ -532,7 +532,7 @@ If you're unhappy with any of the default keyboard bindings you can override the | |||||||
| Reveal.configure({ | Reveal.configure({ | ||||||
|   keyboard: { |   keyboard: { | ||||||
|     13: 'next', // go to the next slide when the ENTER key is pressed |     13: 'next', // go to the next slide when the ENTER key is pressed | ||||||
|     27: function() {}, // do something custom when ESC is pressed |     27: () => { console.log('esc') }, // do something custom when ESC is pressed | ||||||
|     32: null // don't do anything when SPACE is pressed (i.e. disable a reveal.js default binding) |     32: null // don't do anything when SPACE is pressed (i.e. disable a reveal.js default binding) | ||||||
|   } |   } | ||||||
| }); | }); | ||||||
| @@ -598,7 +598,7 @@ Each individual element is decorated with a `data-auto-animate-target` attribute | |||||||
|  |  | ||||||
| Each time a presentation navigates between two auto-animated slides it dispatches the `autoanimate` event. | Each time a presentation navigates between two auto-animated slides it dispatches the `autoanimate` event. | ||||||
| ```javascript | ```javascript | ||||||
| Reveal.on( 'autoanimate', function( event ) { | Reveal.on( 'autoanimate', event => { | ||||||
|   // event.fromSlide, event.toSlide |   // event.fromSlide, event.toSlide | ||||||
| } ); | } ); | ||||||
| ``` | ``` | ||||||
| @@ -749,12 +749,12 @@ For example | |||||||
| //      keyCode: the keycode for binding to the callback | //      keyCode: the keycode for binding to the callback | ||||||
| //          key: the key label to show in the help overlay | //          key: the key label to show in the help overlay | ||||||
| //  description: the description of the action to show in the help overlay | //  description: the description of the action to show in the help overlay | ||||||
| Reveal.addKeyBinding( { keyCode: 84, key: 'T', description: 'Start timer' }, function() { | Reveal.addKeyBinding( { keyCode: 84, key: 'T', description: 'Start timer' }, () => { | ||||||
|   // start timer |   // start timer | ||||||
| } ) | } ) | ||||||
|  |  | ||||||
| // The binding parameter can also be a direct keycode without providing the help description | // The binding parameter can also be a direct keycode without providing the help description | ||||||
| Reveal.addKeyBinding( 82, function() { | Reveal.addKeyBinding( 82, () => { | ||||||
|   // reset timer |   // reset timer | ||||||
| } ) | } ) | ||||||
| ``` | ``` | ||||||
| @@ -764,18 +764,24 @@ This allows plugins to add key bindings directly to Reveal so they can | |||||||
| * make use of Reveal's pre-processing logic for key handling (for example, ignoring key presses when paused); and | * make use of Reveal's pre-processing logic for key handling (for example, ignoring key presses when paused); and | ||||||
| * be included in the help overlay (optional) | * be included in the help overlay (optional) | ||||||
|  |  | ||||||
| ### Slide Changed Event | ### Slide Change Events | ||||||
|  |  | ||||||
| A `slidechanged` event is fired each time the slide is changed (regardless of state). The event object holds the index values of the current slide as well as a reference to the previous and current slide HTML nodes. | A `slidechanged` event is fired each time the slide is changed. The event object holds the index values of the current slide as well as a reference to the previous and current slide DOM nodes. | ||||||
|  |  | ||||||
| Some libraries, like MathJax (see [#226](https://github.com/hakimel/reveal.js/issues/226#issuecomment-10261609)), get confused by the transforms and display states of slides. Often times, this can be fixed by calling their update or render function from this callback. | Some libraries, like MathJax (see [#226](https://github.com/hakimel/reveal.js/issues/226#issuecomment-10261609)), get confused by the transforms and display states of slides. Often times, this can be fixed by calling their update or render function from this callback. | ||||||
|  |  | ||||||
| ```javascript | ```javascript | ||||||
| Reveal.on( 'slidechanged', function( event ) { | Reveal.on( 'slidechanged', event => { | ||||||
|   // event.previousSlide, event.currentSlide, event.indexh, event.indexv |   // event.previousSlide, event.currentSlide, event.indexh, event.indexv | ||||||
| } ); | } ); | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | The `slidechanged` event fires instantly when the slide changes. If you'd rather invoke your event listener when the slide has finished transitioning and is fully visible, you can use the `slidetransitionend` event. The `slidetransitionend` event includes the same event data as described above. | ||||||
|  |  | ||||||
|  | ```javascript | ||||||
|  | Reveal.on( 'slidetransitionend', event => console.log( event.currentSlide ) ); | ||||||
|  | ``` | ||||||
|  |  | ||||||
| ### Presentation State | ### Presentation State | ||||||
|  |  | ||||||
| The presentation's current state can be fetched by using the `getState` method. A state object contains all of the information required to put the presentation back as it was when `getState` was first called. Sort of like a snapshot. It's a simple object that can easily be stringified and persisted or sent over the wire. | The presentation's current state can be fetched by using the `getState` method. A state object contains all of the information required to put the presentation back as it was when `getState` was first called. Sort of like a snapshot. It's a simple object that can easily be stringified and persisted or sent over the wire. | ||||||
| @@ -800,7 +806,7 @@ If you set `data-state="somestate"` on a slide `<section>`, "somestate" will be | |||||||
| Furthermore you can also listen to these changes in state via JavaScript: | Furthermore you can also listen to these changes in state via JavaScript: | ||||||
|  |  | ||||||
| ```javascript | ```javascript | ||||||
| Reveal.on( 'somestate', function() { | Reveal.on( 'somestate', () => { | ||||||
|   // TODO: Sprinkle magic |   // TODO: Sprinkle magic | ||||||
| }, false ); | }, false ); | ||||||
| ``` | ``` | ||||||
| @@ -1007,10 +1013,10 @@ When a slide fragment is either shown or hidden reveal.js will dispatch an event | |||||||
| Some libraries, like MathJax (see #505), get confused by the initially hidden fragment elements. Often times this can be fixed by calling their update or render function from this callback. | Some libraries, like MathJax (see #505), get confused by the initially hidden fragment elements. Often times this can be fixed by calling their update or render function from this callback. | ||||||
|  |  | ||||||
| ```javascript | ```javascript | ||||||
| Reveal.on( 'fragmentshown', function( event ) { | Reveal.on( 'fragmentshown', event => { | ||||||
|   // event.fragment = the fragment DOM element |   // event.fragment = the fragment DOM element | ||||||
| } ); | } ); | ||||||
| Reveal.on( 'fragmenthidden', function( event ) { | Reveal.on( 'fragmenthidden', event => { | ||||||
|   // event.fragment = the fragment DOM element |   // event.fragment = the fragment DOM element | ||||||
| } ); | } ); | ||||||
| ``` | ``` | ||||||
| @@ -1089,7 +1095,7 @@ Reveal.configure({ slideNumber: true }); | |||||||
| Reveal.configure({ slideNumber: 'c/t' }); | Reveal.configure({ slideNumber: 'c/t' }); | ||||||
|  |  | ||||||
| // You can provide a function to fully customize the number: | // You can provide a function to fully customize the number: | ||||||
| Reveal.configure({ slideNumber: function( slide ) { | Reveal.configure({ slideNumber: slide => { | ||||||
|     // Ignore numbering of vertical slides |     // Ignore numbering of vertical slides | ||||||
|     return [ Reveal.getIndices( slide ).h ]; |     return [ Reveal.getIndices( slide ).h ]; | ||||||
| }}); | }}); | ||||||
| @@ -1107,8 +1113,8 @@ Press »ESC« or »O« keys to toggle the overview mode on and off. While you're | |||||||
| as if you were at 1,000 feet above your presentation. The overview mode comes with a few API hooks: | as if you were at 1,000 feet above your presentation. The overview mode comes with a few API hooks: | ||||||
|  |  | ||||||
| ```javascript | ```javascript | ||||||
| Reveal.on( 'overviewshown', function( event ) { /* ... */ } ); | Reveal.on( 'overviewshown', event => { /* ... */ } ); | ||||||
| Reveal.on( 'overviewhidden', function( event ) { /* ... */ } ); | Reveal.on( 'overviewhidden', event => { /* ... */ } ); | ||||||
|  |  | ||||||
| // Toggle the overview mode programmatically | // Toggle the overview mode programmatically | ||||||
| Reveal.toggleOverview(); | Reveal.toggleOverview(); | ||||||
| @@ -1154,7 +1160,7 @@ Limitations: | |||||||
| When reveal.js changes the scale of the slides it fires a resize event. You can subscribe to the event to resize your elements accordingly. | When reveal.js changes the scale of the slides it fires a resize event. You can subscribe to the event to resize your elements accordingly. | ||||||
|  |  | ||||||
| ```javascript | ```javascript | ||||||
| Reveal.on( 'resize', function( event ) { | Reveal.on( 'resize', event => { | ||||||
|   // event.scale, event.oldScale, event.size |   // event.scale, event.oldScale, event.size | ||||||
| } ); | } ); | ||||||
| ``` | ``` | ||||||
| @@ -1172,7 +1178,7 @@ The framework has a built-in postMessage API that can be used when communicating | |||||||
| When reveal.js runs inside of an iframe it can optionally bubble all of its events to the parent. Bubbled events are stringified JSON with three fields: namespace, eventName and state. Here's how you subscribe to them from the parent window: | When reveal.js runs inside of an iframe it can optionally bubble all of its events to the parent. Bubbled events are stringified JSON with three fields: namespace, eventName and state. Here's how you subscribe to them from the parent window: | ||||||
|  |  | ||||||
| ```javascript | ```javascript | ||||||
| window.addEventListener( 'message', function( event ) { | window.addEventListener( 'message', event => { | ||||||
|   var data = JSON.parse( event.data ); |   var data = JSON.parse( event.data ); | ||||||
|   if( data.namespace === 'reveal' && data.eventName === 'slidechanged' ) { |   if( data.namespace === 'reveal' && data.eventName === 'slidechanged' ) { | ||||||
|     // Slide changed, see data.state for slide number |     // Slide changed, see data.state for slide number | ||||||
| @@ -1187,7 +1193,7 @@ When you call any method via the postMessage API, reveal.js will dispatch a mess | |||||||
| ```javascript | ```javascript | ||||||
| <revealWindow>.postMessage( JSON.stringify({ method: 'getTotalSlides' }), '*' ); | <revealWindow>.postMessage( JSON.stringify({ method: 'getTotalSlides' }), '*' ); | ||||||
|  |  | ||||||
| window.addEventListener( 'message', function( event ) { | window.addEventListener( 'message', event => { | ||||||
|   var data = JSON.parse( event.data ); |   var data = JSON.parse( event.data ); | ||||||
|   // `data.method`` is the method that we invoked |   // `data.method`` is the method that we invoked | ||||||
|   if( data.namespace === 'reveal' && data.eventName === 'callback' && data.method === 'getTotalSlides' ) { |   if( data.namespace === 'reveal' && data.eventName === 'callback' && data.method === 'getTotalSlides' ) { | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								dist/reveal.es5.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/reveal.es5.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/reveal.es5.js.map
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/reveal.es5.js.map
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/reveal.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/reveal.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/reveal.js.map
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/reveal.js.map
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										26
									
								
								js/reveal.js
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								js/reveal.js
									
									
									
									
									
								
							| @@ -83,6 +83,9 @@ export default function( revealElement, options ) { | |||||||
| 		// Flags if the interaction event listeners are bound | 		// Flags if the interaction event listeners are bound | ||||||
| 		eventsAreBound = false, | 		eventsAreBound = false, | ||||||
|  |  | ||||||
|  | 		// The current slide transition state; idle or running | ||||||
|  | 		transition = 'idle', | ||||||
|  |  | ||||||
| 		// The current auto-slide duration | 		// The current auto-slide duration | ||||||
| 		autoSlide = 0, | 		autoSlide = 0, | ||||||
|  |  | ||||||
| @@ -484,6 +487,7 @@ export default function( revealElement, options ) { | |||||||
| 		if( config.progress ) progress.bind(); | 		if( config.progress ) progress.bind(); | ||||||
| 		controls.bind(); | 		controls.bind(); | ||||||
|  |  | ||||||
|  | 		dom.slides.addEventListener( 'transitionend', onTransitionEnd, false ); | ||||||
| 		dom.pauseOverlay.addEventListener( 'click', resume, false ); | 		dom.pauseOverlay.addEventListener( 'click', resume, false ); | ||||||
|  |  | ||||||
| 		if( config.focusBodyOnPageVisibilityChange ) { | 		if( config.focusBodyOnPageVisibilityChange ) { | ||||||
| @@ -507,6 +511,7 @@ export default function( revealElement, options ) { | |||||||
| 		window.removeEventListener( 'hashchange', onWindowHashChange, false ); | 		window.removeEventListener( 'hashchange', onWindowHashChange, false ); | ||||||
| 		window.removeEventListener( 'resize', onWindowResize, false ); | 		window.removeEventListener( 'resize', onWindowResize, false ); | ||||||
|  |  | ||||||
|  | 		dom.slides.removeEventListener( 'transitionend', onTransitionEnd, false ); | ||||||
| 		dom.pauseOverlay.removeEventListener( 'click', resume, false ); | 		dom.pauseOverlay.removeEventListener( 'click', resume, false ); | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
| @@ -1197,6 +1202,7 @@ export default function( revealElement, options ) { | |||||||
|  |  | ||||||
| 		// Detect if we're moving between two auto-animated slides | 		// Detect if we're moving between two auto-animated slides | ||||||
| 		if( slideChanged && previousSlide && currentSlide && !overview.isActive() ) { | 		if( slideChanged && previousSlide && currentSlide && !overview.isActive() ) { | ||||||
|  |  | ||||||
| 			// If this is an auto-animated transition, we disable the | 			// If this is an auto-animated transition, we disable the | ||||||
| 			// regular slide transition | 			// regular slide transition | ||||||
| 			// | 			// | ||||||
| @@ -1207,6 +1213,9 @@ export default function( revealElement, options ) { | |||||||
| 				autoAnimateTransition = true; | 				autoAnimateTransition = true; | ||||||
| 				dom.slides.classList.add( 'disable-slide-transitions' ); | 				dom.slides.classList.add( 'disable-slide-transitions' ); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | 			transition = 'running'; | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Update the visibility of slides now that the indices have changed | 		// Update the visibility of slides now that the indices have changed | ||||||
| @@ -2251,6 +2260,23 @@ export default function( revealElement, options ) { | |||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Event listener for transition end on the current slide. | ||||||
|  | 	 * | ||||||
|  | 	 * @param {object} [event] | ||||||
|  | 	 */ | ||||||
|  | 	function onTransitionEnd( event ) { | ||||||
|  |  | ||||||
|  | 		if( transition === 'running' && /section/gi.test( event.target.nodeName ) ) { | ||||||
|  | 			transition = 'idle'; | ||||||
|  | 			dispatchEvent({ | ||||||
|  | 				type: 'slidetransitionend', | ||||||
|  | 				data: { indexh, indexv, previousSlide, currentSlide } | ||||||
|  | 			}); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Handler for the window level 'hashchange' event. | 	 * Handler for the window level 'hashchange' event. | ||||||
| 	 * | 	 * | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ | |||||||
| 		<div id="qunit"></div> | 		<div id="qunit"></div> | ||||||
|   		<div id="qunit-fixture"></div> |   		<div id="qunit-fixture"></div> | ||||||
|  |  | ||||||
| 		<div class="reveal" style="display: none;"> | 		<div class="reveal" style="visibility: hidden;"> | ||||||
|  |  | ||||||
| 			<div class="slides"> | 			<div class="slides"> | ||||||
|  |  | ||||||
| @@ -655,6 +655,32 @@ | |||||||
|  |  | ||||||
| 				}); | 				}); | ||||||
|  |  | ||||||
|  | 				QUnit.test( 'slidetransitionend', function( assert ) { | ||||||
|  | 					assert.expect( 2 ); | ||||||
|  | 					let done = assert.async( 2 ); | ||||||
|  | 					let time = Date.now(); | ||||||
|  |  | ||||||
|  | 					let horizontalCallback = event => { | ||||||
|  | 						assert.ok( Date.now() - time > 200, 'horizontal event fired' ); | ||||||
|  | 						done(); | ||||||
|  |  | ||||||
|  | 						let verticalCallback = event => { | ||||||
|  | 							assert.ok( true, 'vertical event fired' ); | ||||||
|  | 							done(); | ||||||
|  | 							Reveal.off( 'slidetransitionend', verticalCallback ); | ||||||
|  | 						} | ||||||
|  |  | ||||||
|  | 						Reveal.off( 'slidetransitionend', horizontalCallback ); | ||||||
|  | 						Reveal.on( 'slidetransitionend', verticalCallback ); | ||||||
|  | 						Reveal.slide( 1, 1 ); | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					Reveal.slide( 0, 0 ); | ||||||
|  | 					Reveal.on( 'slidetransitionend', horizontalCallback ); | ||||||
|  | 					Reveal.slide( 1, 0 ); | ||||||
|  |  | ||||||
|  | 				}); | ||||||
|  |  | ||||||
| 				QUnit.test( 'paused', function( assert ) { | 				QUnit.test( 'paused', function( assert ) { | ||||||
| 					assert.expect( 1 ); | 					assert.expect( 1 ); | ||||||
| 					var done = assert.async(); | 					var done = assert.async(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user