diff --git a/packages/vant/src/image-preview/ImagePreviewItem.tsx b/packages/vant/src/image-preview/ImagePreviewItem.tsx index 3f2f14df3..3bd7fde72 100644 --- a/packages/vant/src/image-preview/ImagePreviewItem.tsx +++ b/packages/vant/src/image-preview/ImagePreviewItem.tsx @@ -251,6 +251,14 @@ export default defineComponent({ } }; + const checkClose = (event: TouchEvent) => { + const isClickOverlay = event.target === swipeItem.value?.$el; + + if (!props.closeOnClickOverlay && isClickOverlay) return; + + emit('close'); + }; + const checkTap = (event: TouchEvent) => { if (fingerNum > 1) { return; @@ -272,19 +280,13 @@ export default defineComponent({ doubleTapTimer = null; toggleScale(); } else { - if ( - !props.closeOnClickOverlay && - event.target === swipeItem.value?.$el - ) { - return; - } doubleTapTimer = setTimeout(() => { - emit('close'); + checkClose(event); doubleTapTimer = null; }, TAP_TIME); } } else { - emit('close'); + checkClose(event); } } // long press diff --git a/packages/vant/src/image-preview/test/index.spec.ts b/packages/vant/src/image-preview/test/index.spec.ts index c6aa42bab..ba74f3dba 100644 --- a/packages/vant/src/image-preview/test/index.spec.ts +++ b/packages/vant/src/image-preview/test/index.spec.ts @@ -7,7 +7,7 @@ import { } from '../../../test'; import { LONG_PRESS_START_TIME } from '../../utils'; import ImagePreview from '../ImagePreview'; -import { images, triggerZoom } from './shared'; +import { images, triggerDoubleTap, triggerZoom } from './shared'; import type { ImagePreviewInstance } from '../types'; test('should swipe to current index after calling the swipeTo method', async () => { @@ -230,38 +230,56 @@ test('should trigger scale after double clicking', async () => { await later(); const swipe = wrapper.find('.van-swipe-item'); - triggerDrag(swipe, 0, 0); - triggerDrag(swipe, 0, 0); + + triggerDoubleTap(swipe); expect(onScale).toHaveBeenCalledWith({ index: 0, scale: 2, }); - await later(); - triggerDrag(swipe, 0, 0); - triggerDrag(swipe, 0, 0); + triggerDoubleTap(swipe); expect(onScale).toHaveBeenLastCalledWith({ index: 0, scale: 1, }); + + // when closeOnClickOverlay is set to false, it will not affect the zooming. + onScale.mockClear(); + await wrapper.setProps({ closeOnClickOverlay: false }); + triggerDoubleTap(swipe); + expect(onScale).toHaveBeenCalled(); }); test('should allow to disable double click gesture', async () => { const onScale = vi.fn(); + const onClose = vi.fn(); const wrapper = mount(ImagePreview, { props: { images, show: true, doubleScale: false, + onClose, onScale, + 'onUpdate:show': (show) => { + wrapper.setProps({ show }); + }, }, }); + // The ImagePreview will close because double-click is disabled. await later(); const swipe = wrapper.find('.van-swipe-item'); - triggerDrag(swipe, 0, 0); - triggerDrag(swipe, 0, 0); - expect(onScale).toHaveBeenCalledTimes(0); + await triggerDoubleTap(swipe); + expect(onClose).toHaveBeenCalled(); + expect(onScale).not.toHaveBeenCalled(); + + // The ImagePreview will not close when closeOnClickOverlay is set to false. + onClose.mockClear(); + await wrapper.setProps({ closeOnClickOverlay: false, show: true }); + await triggerDrag(swipe, 0, 0); + expect(onClose).not.toHaveBeenCalled(); + await triggerDoubleTap(swipe, 0, 0); + expect(onClose).not.toHaveBeenCalled(); }); test('zoom in and drag image to move', async () => { diff --git a/packages/vant/src/image-preview/test/shared.ts b/packages/vant/src/image-preview/test/shared.ts index 772c4617e..d958e00ec 100644 --- a/packages/vant/src/image-preview/test/shared.ts +++ b/packages/vant/src/image-preview/test/shared.ts @@ -1,6 +1,7 @@ +import { nextTick } from 'vue'; import { DOMWrapper } from '@vue/test-utils/dist/domWrapper'; import { cdnURL } from '../../../docs/site'; -import { trigger } from '../../../test'; +import { trigger, triggerDrag } from '../../../test'; export const images = [ cdnURL('apple-1.jpeg'), @@ -38,3 +39,14 @@ export function triggerZoom( trigger(el, 'touchend', 0, 0, { touchList: [] }); } + +export function triggerDoubleTap( + el: HTMLElement | DOMWrapper, + x: number = 0, + y: number = 0, +) { + triggerDrag(el, x, y); + triggerDrag(el, x, y); + + return nextTick(); +}