Procházet zdrojové kódy

Bug Fix: After the carousel is shifted, it may be rewound back when going opposite direction against the shifted one.

Naotoshi Fujita před 2 roky
rodič
revize
b164d15184

+ 13 - 7
dist/js/splide.cjs.js

@@ -1192,9 +1192,10 @@ const Move = (Splide, Components, options, event) => {
     }
   }
   function move(dest, index, prev, callback) {
-    Transition.cancel();
-    if (dest !== index && canShift(dest > prev)) {
-      translate(shift(getPosition(), dest > prev), true);
+    const forward = dest > prev;
+    cancel();
+    if ((dest !== index || exceededLimit(forward)) && canShift(forward)) {
+      translate(shift(getPosition(), forward), true);
     }
     indices = [index, prev, dest];
     set(MOVING);
@@ -1361,15 +1362,17 @@ const Controller = (Splide, Components, options, event) => {
     if (!isBusy()) {
       const dest = parse(control);
       const index = loop(dest);
-      const validIndex = index > -1 && (allowSameIndex || index !== currIndex);
-      const canMove = dest === index || Move.canShift(dest > prevIndex);
-      if (validIndex && canMove) {
+      if (canGo(dest, index)) {
         Scroll.cancel();
         setIndex(index);
         Move.move(dest, index, prevIndex, callback);
       }
     }
   }
+  function canGo(dest, index) {
+    const forward = dest > prevIndex;
+    return index > -1 && (index !== currIndex || !isMoving()) && (dest === index || Move.exceededLimit(!forward) || Move.canShift(forward));
+  }
   function jump(control) {
     const { set } = Components.Breakpoints;
     const { speed } = options;
@@ -1484,8 +1487,11 @@ const Controller = (Splide, Components, options, event) => {
   function hasFocus() {
     return !isUndefined(options.focus) || options.isNavigation;
   }
+  function isMoving() {
+    return Splide.state.is([MOVING, SCROLLING]);
+  }
   function isBusy() {
-    return Splide.state.is([MOVING, SCROLLING]) && !!options.waitForTransition;
+    return isMoving() && !!options.waitForTransition;
   }
   return {
     mount,

+ 13 - 7
dist/js/splide.esm.js

@@ -1188,9 +1188,10 @@ const Move = (Splide, Components, options, event) => {
     }
   }
   function move(dest, index, prev, callback) {
-    Transition.cancel();
-    if (dest !== index && canShift(dest > prev)) {
-      translate(shift(getPosition(), dest > prev), true);
+    const forward = dest > prev;
+    cancel();
+    if ((dest !== index || exceededLimit(forward)) && canShift(forward)) {
+      translate(shift(getPosition(), forward), true);
     }
     indices = [index, prev, dest];
     set(MOVING);
@@ -1357,15 +1358,17 @@ const Controller = (Splide, Components, options, event) => {
     if (!isBusy()) {
       const dest = parse(control);
       const index = loop(dest);
-      const validIndex = index > -1 && (allowSameIndex || index !== currIndex);
-      const canMove = dest === index || Move.canShift(dest > prevIndex);
-      if (validIndex && canMove) {
+      if (canGo(dest, index)) {
         Scroll.cancel();
         setIndex(index);
         Move.move(dest, index, prevIndex, callback);
       }
     }
   }
+  function canGo(dest, index) {
+    const forward = dest > prevIndex;
+    return index > -1 && (index !== currIndex || !isMoving()) && (dest === index || Move.exceededLimit(!forward) || Move.canShift(forward));
+  }
   function jump(control) {
     const { set } = Components.Breakpoints;
     const { speed } = options;
@@ -1480,8 +1483,11 @@ const Controller = (Splide, Components, options, event) => {
   function hasFocus() {
     return !isUndefined(options.focus) || options.isNavigation;
   }
+  function isMoving() {
+    return Splide.state.is([MOVING, SCROLLING]);
+  }
   function isBusy() {
-    return Splide.state.is([MOVING, SCROLLING]) && !!options.waitForTransition;
+    return isMoving() && !!options.waitForTransition;
   }
   return {
     mount,

+ 13 - 7
dist/js/splide.js

@@ -1188,9 +1188,10 @@
       }
     }
     function move(dest, index, prev, callback) {
-      Transition.cancel();
-      if (dest !== index && canShift(dest > prev)) {
-        translate(shift(getPosition(), dest > prev), true);
+      const forward = dest > prev;
+      cancel();
+      if ((dest !== index || exceededLimit(forward)) && canShift(forward)) {
+        translate(shift(getPosition(), forward), true);
       }
       indices = [index, prev, dest];
       set(MOVING);
@@ -1357,15 +1358,17 @@
       if (!isBusy()) {
         const dest = parse(control);
         const index = loop(dest);
-        const validIndex = index > -1 && (allowSameIndex || index !== currIndex);
-        const canMove = dest === index || Move.canShift(dest > prevIndex);
-        if (validIndex && canMove) {
+        if (canGo(dest, index)) {
           Scroll.cancel();
           setIndex(index);
           Move.move(dest, index, prevIndex, callback);
         }
       }
     }
+    function canGo(dest, index) {
+      const forward = dest > prevIndex;
+      return index > -1 && (index !== currIndex || !isMoving()) && (dest === index || Move.exceededLimit(!forward) || Move.canShift(forward));
+    }
     function jump(control) {
       const { set } = Components.Breakpoints;
       const { speed } = options;
@@ -1480,8 +1483,11 @@
     function hasFocus() {
       return !isUndefined(options.focus) || options.isNavigation;
     }
+    function isMoving() {
+      return Splide.state.is([MOVING, SCROLLING]);
+    }
     function isBusy() {
-      return Splide.state.is([MOVING, SCROLLING]) && !!options.waitForTransition;
+      return isMoving() && !!options.waitForTransition;
     }
     return {
       mount,

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/splide.min.js


binární
dist/js/splide.min.js.gz


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
dist/js/splide.min.js.map


+ 33 - 6
src/js/components/Controller/Controller.ts

@@ -134,12 +134,10 @@ export const Controller: ComponentConstructor<ControllerComponent> = ( Splide, C
    */
   function go( control: number | string, allowSameIndex?: boolean, callback?: AnyFunction ): void {
     if ( ! isBusy() ) {
-      const dest       = parse( control );
-      const index      = loop( dest );
-      const validIndex = index > -1 && ( allowSameIndex || index !== currIndex );
-      const canMove    = dest === index || Move.canShift( dest > prevIndex );
+      const dest  = parse( control );
+      const index = loop( dest );
 
-      if ( validIndex && canMove ) {
+      if ( canGo( dest, index ) ) {
         Scroll.cancel();
         setIndex( index );
         Move.move( dest, index, prevIndex, callback );
@@ -147,6 +145,26 @@ export const Controller: ComponentConstructor<ControllerComponent> = ( Splide, C
     }
   }
 
+  /**
+   * Checks if the carousel can move or not.
+   * - If target and current index are same, allows going only when the carousel is not moving.
+   *   Otherwise, synced carousels will provoke the infinite loop.
+   * - If the carousel is looping (`dest !== index`),
+   *   the carousel can be shifted or has been already shifted.
+   *
+   * @param dest  - A dest index.
+   * @param index - An actual index.
+   *
+   * @return `true` if the carousel can currently move, or otherwise `false`.
+   */
+  function canGo( dest: number, index: number ): boolean {
+    const forward = dest > prevIndex;
+
+    return index > -1
+      &&( index !== currIndex || ! isMoving() )
+      && ( dest === index || Move.exceededLimit( ! forward ) || Move.canShift( forward ) );
+  }
+
   /**
    * Immediately jumps to the specified index.
    *
@@ -395,13 +413,22 @@ export const Controller: ComponentConstructor<ControllerComponent> = ( Splide, C
     return ! isUndefined( options.focus ) || options.isNavigation;
   }
 
+  /**
+   * Checks if the carousel is moving now or not.
+   *
+   * @return `true` if the carousel is moving or scrolling, or otherwise `false`.
+   */
+  function isMoving(): boolean {
+    return Splide.state.is( [ MOVING, SCROLLING ] );
+  }
+
   /**
    * Checks if the slider is moving/scrolling or not.
    *
    * @return `true` if the slider can move, or otherwise `false`.
    */
   function isBusy(): boolean {
-    return Splide.state.is( [ MOVING, SCROLLING ] ) && !! options.waitForTransition;
+    return isMoving() && !! options.waitForTransition;
   }
 
   return {

+ 9 - 3
src/js/components/Move/Move.ts

@@ -89,6 +89,10 @@ export const Move: ComponentConstructor<MoveComponent> = ( Splide, Components, o
 
   /**
    * Moves the slider to the dest index with the Transition component.
+   * Needs to shift the carousel when:
+   * - Crossing bounds (`dest !== index && ! exceededLimit( ! forward )`).
+   *   But the second condition is not necessary because of `canShift()`.
+   * - Going further although the carousel already outside bounds (`exceededLimit( forward )`)
    *
    * @param dest     - A destination index to go to, including clones'.
    * @param index    - A slide index.
@@ -96,10 +100,12 @@ export const Move: ComponentConstructor<MoveComponent> = ( Splide, Components, o
    * @param callback - Optional. A callback function invoked after transition ends.
    */
   function move( dest: number, index: number, prev: number, callback?: AnyFunction ): void {
-    Transition.cancel();
+    const forward = dest > prev;
 
-    if ( dest !== index && canShift( dest > prev ) ) {
-      translate( shift( getPosition(), dest > prev ), true );
+    cancel();
+
+    if ( ( dest !== index || exceededLimit( forward ) ) && canShift( forward ) ) {
+      translate( shift( getPosition(), forward ), true );
     }
 
     indices = [ index, prev, dest ];

+ 2 - 1
src/js/test/php/examples/rtl.php

@@ -19,8 +19,9 @@ $settings = get_settings();
   <script>
     document.addEventListener( 'DOMContentLoaded', function () {
       var splide = new Splide( '#splide01', {
-        type     : 'slide',
+        type     : 'loop',
         perPage  : 3,
+        gap      : 5,
         direction: 'rtl',
         rewind   : true,
         padding  : {

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů