瀏覽代碼

polyfill element.closest for ie11

Hakim El Hattab 5 年之前
父節點
當前提交
b7487b8b4f

文件差異過大導致無法顯示
+ 0 - 0
dist/reveal.esm.js


文件差異過大導致無法顯示
+ 0 - 0
dist/reveal.js


+ 0 - 0
examples/slide-backgrounds.html → examples/backgrounds.html


+ 12 - 0
examples/media.html

@@ -36,6 +36,18 @@
 					<audio src="assets/beeping.wav" data-autoplay></audio>
 				</section>
 
+				<section>
+					<h2>Audio inside slide fragments</h2>
+					<div class="fragment">
+						Beep 1
+						<audio src="assets/beeping.wav" data-autoplay></audio>
+					</div>
+					<div class="fragment">
+						Beep 2
+						<audio src="assets/beeping.wav" data-autoplay></audio>
+					</div>
+				</section>
+
 				<section>
 					<h2>Audio with controls</h2>
 					<audio src="assets/beeping.wav" controls></audio>

+ 0 - 0
examples/slide-transitions.html → examples/transitions.html


+ 5 - 5
js/controllers/autoanimate.js

@@ -1,4 +1,4 @@
-import { queryAll, extend, createStyleSheet, matchesSelector } from '../utils/util.js'
+import { queryAll, extend, createStyleSheet, matches, closest } from '../utils/util.js'
 import { FRAGMENT_STYLE_REGEX } from '../utils/constants.js'
 
 // Counter used to generate unique IDs for auto-animated elements
@@ -299,8 +299,8 @@ export default class AutoAnimate {
 		options = extend( options, inheritedOptions );
 
 		// Inherit options from parent elements
-		if( element.closest && element.parentNode ) {
-			let autoAnimatedParent = element.parentNode.closest( '[data-auto-animate-target]' );
+		if( element.parentNode ) {
+			let autoAnimatedParent = closest( element.parentNode, '[data-auto-animate-target]' );
 			if( autoAnimatedParent ) {
 				options = this.getAutoAnimateOptions( autoAnimatedParent, options );
 			}
@@ -463,11 +463,11 @@ export default class AutoAnimate {
 
 			// Disable scale transformations on text nodes, we transiition
 			// each individual text property instead
-			if( matchesSelector( pair.from, textNodes ) ) {
+			if( matches( pair.from, textNodes ) ) {
 				pair.options = { scale: false };
 			}
 			// Animate individual lines of code
-			else if( matchesSelector( pair.from, codeNodes ) ) {
+			else if( matches( pair.from, codeNodes ) ) {
 
 				// Transition the code block's width and height instead of scaling
 				// to prevent its content from being squished

+ 3 - 1
js/controllers/focus.js

@@ -1,3 +1,5 @@
+import { closest } from '../utils/util.js'
+
 /**
  * Manages focus when a presentation is embedded. This
  * helps us only capture keyboard from the presentation
@@ -85,7 +87,7 @@ export default class Focus {
 
 	onDocumentPointerDown( event ) {
 
-		let revealElement = event.target.closest( '.reveal' );
+		let revealElement = closest( event.target, '.reveal' );
 		if( !revealElement || revealElement !== this.Reveal.getRevealElement() ) {
 			this.blur();
 		}

+ 10 - 10
js/controllers/slidecontent.js

@@ -1,5 +1,5 @@
 import { HORIZONTAL_SLIDES_SELECTOR, VERTICAL_SLIDES_SELECTOR } from '../utils/constants.js'
-import { extend, queryAll, closestParent } from '../utils/util.js'
+import { extend, queryAll, closest } from '../utils/util.js'
 import { isMobile } from '../utils/device.js'
 
 /**
@@ -240,7 +240,7 @@ export default class SlideContent {
 
 			// HTML5 media elements
 			queryAll( element, 'video, audio' ).forEach( el => {
-				if( closestParent( el, '.fragment' ) && !closestParent( el, '.fragment.visible' ) ) {
+				if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
 					return;
 				}
 
@@ -250,7 +250,7 @@ export default class SlideContent {
 				// If no global setting is available, fall back on the element's
 				// own autoplay setting
 				if( typeof autoplay !== 'boolean' ) {
-					autoplay = el.hasAttribute( 'data-autoplay' ) || !!closestParent( el, '.slide-background' );
+					autoplay = el.hasAttribute( 'data-autoplay' ) || !!closest( el, '.slide-background' );
 				}
 
 				if( autoplay && typeof el.play === 'function' ) {
@@ -288,7 +288,7 @@ export default class SlideContent {
 
 			// Normal iframes
 			queryAll( element, 'iframe[src]' ).forEach( el => {
-				if( closestParent( el, '.fragment' ) && !closestParent( el, '.fragment.visible' ) ) {
+				if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
 					return;
 				}
 
@@ -297,7 +297,7 @@ export default class SlideContent {
 
 			// Lazy loading iframes
 			queryAll( element, 'iframe[data-src]' ).forEach( el => {
-				if( closestParent( el, '.fragment' ) && !closestParent( el, '.fragment.visible' ) ) {
+				if( closest( el, '.fragment' ) && !closest( el, '.fragment.visible' ) ) {
 					return;
 				}
 
@@ -320,8 +320,8 @@ export default class SlideContent {
 	 */
 	startEmbeddedMedia( event ) {
 
-		let isAttachedToDOM = !!closestParent( event.target, 'html' ),
-			isVisible  		= !!closestParent( event.target, '.present' );
+		let isAttachedToDOM = !!closest( event.target, 'html' ),
+			isVisible  		= !!closest( event.target, '.present' );
 
 		if( isAttachedToDOM && isVisible ) {
 			event.target.currentTime = 0;
@@ -344,8 +344,8 @@ export default class SlideContent {
 
 		if( iframe && iframe.contentWindow ) {
 
-			let isAttachedToDOM = !!closestParent( event.target, 'html' ),
-				isVisible  		= !!closestParent( event.target, '.present' );
+			let isAttachedToDOM = !!closest( event.target, 'html' ),
+				isVisible  		= !!closest( event.target, '.present' );
 
 			if( isAttachedToDOM && isVisible ) {
 
@@ -355,7 +355,7 @@ export default class SlideContent {
 				// If no global setting is available, fall back on the element's
 				// own autoplay setting
 				if( typeof autoplay !== 'boolean' ) {
-					autoplay = iframe.hasAttribute( 'data-autoplay' ) || !!closestParent( iframe, '.slide-background' );
+					autoplay = iframe.hasAttribute( 'data-autoplay' ) || !!closest( iframe, '.slide-background' );
 				}
 
 				// YouTube postMessage API

+ 1 - 1
js/reveal.js

@@ -148,7 +148,7 @@ export default function( revealElement, options ) {
 
 		// Embedded decks use the reveal element as their viewport
 		if( config.embedded === true ) {
-			dom.viewport = revealElement.closest( '.reveal-viewport' ) || revealElement;
+			dom.viewport = Util.closest( revealElement, '.reveal-viewport' ) || revealElement;
 		}
 		// Full-page decks use the body as their viewport
 		else {

+ 12 - 15
js/utils/util.js

@@ -94,14 +94,10 @@ export const transformElement = ( element, transform ) => {
  *
  * @return {Boolean}
  */
-export const matchesSelector = ( target, selector ) => {
+export const matches = ( target, selector ) => {
 
-	// There's some overhead doing this each time, we don't
-	// want to rewrite the element prototype but should still
-	// be enough to feature detect once at startup...
-	let matchesMethod = parent.matches || parent.matchesSelector || parent.msMatchesSelector;
+	let matchesMethod = target.matches || target.matchesSelector || target.msMatchesSelector;
 
-	// If we find a match, we're all set
 	return !!( matchesMethod && matchesMethod.call( target, selector ) );
 
 }
@@ -117,20 +113,21 @@ export const matchesSelector = ( target, selector ) => {
  * @return {HTMLElement} The matched parent or null
  * if no matching parent was found
  */
-export const closestParent = ( target, selector ) => {
+export const closest = ( target, selector ) => {
 
-	let parent = target.parentNode;
-
-	while( parent ) {
+	// Native Element.closest
+	if( typeof target.closest === 'function' ) {
+		return target.closest( selector );
+	}
 
-		// If we find a match, we're all set
-		if( matchesSelector( parent, selector ) ) {
-			return parent;
+	// Polyfill
+	while( target ) {
+		if( matches( target, selector ) ) {
+			return target;
 		}
 
 		// Keep searching
-		parent = parent.parentNode;
-
+		target = target.parentNode;
 	}
 
 	return null;

部分文件因文件數量過多而無法顯示