Does Swiper's parent automatically block touch when a nested child Swiper is active?
0 reputation · 16 Jun 2024, 04:22 UTC
0 reputation · 16 Jun 2024, 04:22 UTC
Swiper supports nested carousels via the nested option. When both parent and child Swipers have allowTouchMove enabled, the library’s event delegation may let the child consume a swipe, but the parent can still register a touchstart and trigger a slide change.
The current documentation does not specify whether the parent automatically blocks touch events when a child is active, nor how touchStartPreventDefault interacts with this scenario. This creates a race condition that can produce inconsistent UX.
nested:true?allowTouchMove setting on the parent influence this behavior?Yes. When the parent Swiper is initialized with nested: true and the child Swiper is initialized with touch moves enabled, the parent ignores pointer events while a drag is active over the child. The child consumes the swipe and the parent does not change slides. This suppression is not automatic when nested is omitted or false; in that configuration the parent can still receive touchstart and slide while the child is being dragged.
Likely explanation: Swiper's nested mode handles pointers at the container level and suppresses the parent's own touch tracking when a drag originates inside an active child instance. The parent's allowTouchMove does not re-enable parent touches during that child drag; nested: true takes precedence. Setting allowTouchMove: false, or a function returning false, blocks the parent independently of the child state.
Behavior to verify:
allowTouchMove enabled, which is the default, for nested suppression to engage.pointer-events: none, the parent may still receive touches.nested: true.allowTouchMove: true, which is the default.touchstart listener on the parent wrapper and confirm it does not fire while dragging the child.allowTouchMove: false or a function returning false.const parent = new Swiper('.parent', {
nested: true,
allowTouchMove: true,
});
const child = new Swiper('.child', {
// allowTouchMove defaults to true
});
Drag the child and confirm the parent slide index does not change. Then set parent nested: false and repeat; the parent should now slide while the child is dragged. Run the same steps in Swiper 8.x and 9.x to confirm identical outcomes.
Are you using lazy-loaded or virtual slides inside the child? Delayed child rendering can temporarily break nested touch blocking until the child is ready.
Use comments to ask for clarification. Post a solution as an answer.
5,640 reputation · 16 Jun 2024, 12:57 UTC
When nested:true is set on a child Swiper, the library adds a touchmove listener that calls event.stopPropagation(), so the parent never receives move events while the child is being dragged. Touchstart events still bubble unless the child also sets touchStartPreventDefault:true, which prevents default and stops propagation. The parent’s allowTouchMove flag does not change this behavior; it only gates whether the parent will react to events that do reach it. Touchend (and touchcancel) always bubble unless explicitly prevented.