瀏覽代碼

Bug Fix and Refactoring: page.updated event was registered over once. Reduce unnecessary recalculations.

NaotoshiFujita 5 年之前
父節點
當前提交
33788d1680

文件差異過大導致無法顯示
+ 0 - 0
dist/css/splide.min.css


文件差異過大導致無法顯示
+ 0 - 0
dist/css/themes/splide-default.min.css


文件差異過大導致無法顯示
+ 1 - 1
dist/js/splide.min.js


二進制
dist/js/splide.min.js.gz


+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "@splidejs/splide",
-  "version": "1.0.21",
+  "version": "1.0.22",
   "description": "Splide is a lightweight and powerful slider without any dependencies.",
   "author": "Naotoshi Fujita",
   "license": "MIT",

+ 10 - 20
src/js/components/layout/index.js

@@ -17,7 +17,7 @@ import { subscribe, applyStyle } from '../../utils/dom';
  *
  * @type {number}
  */
-const THROTTLE = 30;
+const THROTTLE = 50;
 
 
 /**
@@ -160,6 +160,15 @@ export default ( Splide, Components ) => {
 		get padding() {
 			return Resolver.padding;
 		},
+
+		/**
+		 * Return the number of slides in the current view.
+		 *
+		 * @return {number} - The number of slides in view.
+		 */
+		get numInView() {
+			return Resolver.numInView;
+		}
 	};
 
 	/**
@@ -193,10 +202,6 @@ export default ( Splide, Components ) => {
 		const throttledResize = throttle( () => { Splide.emit( 'resize' ) }, THROTTLE );
 		subscribe( window, 'resize', throttledResize );
 		Splide.on( 'mounted resize', resize ).on( 'updated', init );
-
-		if ( ! isVertical ) {
-			Splide.on( 'mounted resize', updatePerPage );
-		}
 	}
 
 	/**
@@ -217,20 +222,5 @@ export default ( Splide, Components ) => {
 		}
 	}
 
-	/**
-	 * Update the perPage number automatically according to the fixedWidth.
-	 */
-	function updatePerPage() {
-		const options = Splide.options;
-
-		if ( options.fixedWidth ) {
-			const perPage = Math.floor( ( Layout.width + Resolver.gap ) / ( Layout.slideWidth + Resolver.gap ) ) || 1;
-
-			if ( options.perPage !== perPage ) {
-				Splide.options = { perPage };
-			}
-		}
-	}
-
 	return Layout;
 }

+ 44 - 39
src/js/components/layout/resolvers/horizontal.js

@@ -27,6 +27,13 @@ export default ( Splide, Components, options ) => {
 	 */
 	const Elements = Components.Elements;
 
+	/**
+	 * Keep the root element.
+	 *
+	 * @type {Element}
+	 */
+	const root = Splide.root;
+
 	/**
 	 * Keep the track element.
 	 *
@@ -57,21 +64,35 @@ export default ( Splide, Components, options ) => {
 		listHeight: 0,
 
 		/**
-		 * Initialization.
+		 * Gap in px.
+		 *
+		 * @type {number}
 		 */
-		init() {
-			let padding = options.padding;
+		gap: toPixel( root, options.gap ),
+
+		/**
+		 * An object containing padding left and right in px.
+		 *
+		 * @type {Object}
+		 */
+		padding: ( () => {
+			const padding = options.padding;
+			const { left = padding, right = padding } = padding;
 
-			if ( padding ) {
-				if ( typeof padding !== 'object' ) {
-					padding = {
-						left : padding,
-						right: padding,
-					}
-				}
+			return {
+				left : toPixel( root, left ),
+				right: toPixel( root, right ),
+			};
+		} )(),
 
-				applyStyle( track, { paddingLeft : unit( padding.left ), paddingRight: unit( padding.right ) } );
-			}
+		/**
+		 * Initialization.
+		 */
+		init() {
+			applyStyle( track, {
+				paddingLeft : unit( this.padding.left ),
+				paddingRight: unit( this.padding.right ),
+			} );
 		},
 
 		/**
@@ -98,13 +119,8 @@ export default ( Splide, Components, options ) => {
 		 * @return {number} - The slide width.
 		 */
 		get slideWidth() {
-			let width = options.fixedWidth;
-
-			if ( ! width ) {
-				width = ( ( this.width + this.gap ) / options.perPage ) - this.gap;
-			}
-
-			return toPixel( Splide.root, width );
+			const width = options.fixedWidth || ( ( this.width + this.gap ) / options.perPage ) - this.gap;
+			return toPixel( root, width );
 		},
 
 		/**
@@ -114,31 +130,20 @@ export default ( Splide, Components, options ) => {
 		 */
 		get slideHeight() {
 			const height = options.height || options.fixedHeight || this.width * options.heightRatio;
-			return toPixel( Splide.root, height );
-		},
-
-		/**
-		 * Return gap in px.
-		 *
-		 * @return {Object} - Gap amount in px.
-		 */
-		get gap() {
-			const style = getComputedStyle( Elements.slides[ 0 ] );
-			return parseFloat( style[ this.marginProp ] ) || 0;
+			return toPixel( root, height );
 		},
 
 		/**
-		 * Return padding object.
+		 * Return the number of slides in the current view.
 		 *
-		 * @return {Object} - An object containing padding left and right.
+		 * @return {number} - The number of slides in view.
 		 */
-		get padding() {
-			const style = getComputedStyle( track );
+		get numInView() {
+			if ( options.fixedWidth ) {
+				return Math.floor( ( this.width + this.gap ) / ( this.slideWidth + this.gap ) ) || 1;
+			}
 
-			return {
-				left  : parseFloat( style.paddingLeft ) || 0,
-				right : parseFloat( style.paddingRight ) || 0,
-			};
-		},
+			return options.perPage;
+		}
 	}
 }

+ 43 - 38
src/js/components/layout/resolvers/vertical.js

@@ -27,6 +27,13 @@ export default ( Splide, Components, options ) => {
 	 */
 	const Elements = Components.Elements;
 
+	/**
+	 * Keep the root element.
+	 *
+	 * @type {Element}
+	 */
+	const root = Splide.root;
+
 	/**
 	 * Keep the track element.
 	 *
@@ -43,21 +50,35 @@ export default ( Splide, Components, options ) => {
 		marginProp: 'marginBottom',
 
 		/**
-		 * Init slider styles according to options.
+		 * Gap in px.
+		 *
+		 * @type {number}
 		 */
-		init() {
-			let padding = options.padding;
+		gap: toPixel( root, options.gap ),
 
-			if ( padding ) {
-				if ( typeof padding !== 'object' ) {
-					padding = {
-						top   : padding,
-						bottom: padding,
-					}
-				}
+		/**
+		 * An object containing padding left and right in px.
+		 *
+		 * @type {Object}
+		 */
+		padding: ( () => {
+			const padding = options.padding;
+			const { top = padding, bottom = padding } = padding;
 
-				applyStyle( track, { paddingTop : unit( padding.top ), paddingBottom: unit( padding.bottom ) } );
-			}
+			return {
+				top   : toPixel( root, top ),
+				bottom: toPixel( root, bottom ),
+			};
+		} )(),
+
+		/**
+		 * Init slider styles according to options.
+		 */
+		init() {
+			applyStyle( track, {
+				paddingTop   : unit( this.padding.top ),
+				paddingBottom: unit( this.padding.bottom ),
+			} );
 		},
 
 		/**
@@ -77,7 +98,7 @@ export default ( Splide, Components, options ) => {
 		get height() {
 			const height = options.height || this.width * options.heightRatio;
 			exist( height, '"height" or "heightRatio" must be given in TTB mode.' );
-			return toPixel( Splide.root, height );
+			return toPixel( Splide.root, height ) - this.padding.top - this.padding.bottom;
 		},
 
 		/**
@@ -113,37 +134,21 @@ export default ( Splide, Components, options ) => {
 		 * @return {number} - The slide height.
 		 */
 		get slideHeight() {
-			let height = options.fixedHeight;
-
-			if ( ! height ) {
-				height = ( this.height + this.gap ) / options.perPage - this.gap;
-			}
-
+			const height = options.fixedHeight || ( this.height + this.gap ) / options.perPage - this.gap;
 			return toPixel( Splide.root, height );
 		},
 
 		/**
-		 * Return gap in px.
-		 *
-		 * @return {Object} - Gap amount in px.
-		 */
-		get gap() {
-			const style = getComputedStyle( Elements.slides[ 0 ] );
-			return parseFloat( style[ this.marginProp ] ) || 0;
-		},
-
-		/**
-		 * Return padding object.
+		 * Return the number of slides in the current view.
 		 *
-		 * @return {Object} - An object containing padding top and bottom.
+		 * @return {number} - The number of slides in view.
 		 */
-		get padding() {
-			const style = getComputedStyle( track );
+		get numInView() {
+			if ( options.fixedHeight ) {
+				return Math.floor( ( this.height + this.gap ) / ( this.slideHeight + this.gap ) ) || 1;
+			}
 
-			return {
-				top   : parseFloat( style.paddingTop ) || 0,
-				bottom: parseFloat( style.paddingBottom ) || 0,
-			};
-		},
+			return options.perPage;
+		}
 	}
 }

+ 10 - 9
src/js/components/slides/slide.js

@@ -69,7 +69,7 @@ export default function Slide( index, realIndex, slide, Splide ) {
 			Splide.on( 'mounted moved updated', () => {
 				this.update( this.isActive(), false );
 				this.update( this.isVisible(), true );
-			} );
+			} ).on( 'resize', () => { this.update( this.isVisible(), true ) } );
 		},
 
 		/**
@@ -108,22 +108,23 @@ export default function Slide( index, realIndex, slide, Splide ) {
 		 * @return {boolean} - True if the slide is visible or false if not.
 		 */
 		isVisible() {
-			const { focus, perPage, trimSpace }  = Splide.options;
+			const { focus, trimSpace }  = Splide.options;
 			const { index: activeIndex, length } = Splide;
-			const isCenter = 'center' === focus;
-			const offset   = isCenter ? perPage / 2 : parseInt( focus ) || 0;
+			const isCenter  = 'center' === focus;
+			const numInView = Splide.Components.Layout.numInView;
+			const offset    = isCenter ? numInView / 2 : parseInt( focus ) || 0;
 
 			if ( trimSpace ) {
 				if ( activeIndex < offset ) {
-					return index < perPage;
-				} else if ( activeIndex >= length - ( perPage - offset ) ) {
-					return index >= length - perPage;
+					return index < numInView;
+				} else if ( activeIndex >= length - ( numInView - offset ) ) {
+					return index >= length - numInView;
 				}
 			}
 
-			const min = activeIndex - offset + ( isCenter && perPage % 2 === 0 ? 1 : 0 );
+			const min = activeIndex - offset + ( isCenter && numInView % 2 === 0 ? 1 : 0 );
 
-			return min <= index && index < activeIndex + perPage - offset;
+			return min <= index && index < activeIndex + numInView - offset;
 		},
 
 		/**

+ 5 - 0
src/js/core/event.js

@@ -29,6 +29,11 @@ export default () => {
 		 */
 		on( event, handler ) {
 			event.split( ' ' ).forEach( name => {
+				// Prevent an event with a namespace from being registered twice.
+				if ( name.indexOf( '.' ) > -1 && handlers[ name ] ) {
+					return;
+				}
+
 				if ( ! handlers[ name ] ) {
 					handlers[ name ] = [];
 				}

+ 27 - 0
src/sass/themes/default/object/modifiers/_rtl.scss

@@ -0,0 +1,27 @@
+.splide {
+  $root: &;
+
+  &--rtl {
+    > #{$root}__track > #{$root}__arrows, > #{$root}__arrows {
+      #{$root}__arrow {
+        &--prev {
+          right: 1em;
+          left: auto;
+
+          svg {
+            transform: scaleX( 1 );
+          }
+        }
+
+        &--next {
+          left: 1em;
+          right: auto;
+
+          svg {
+            transform: scaleX( -1 );
+          }
+        }
+      }
+    }
+  }
+}

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