diff --git a/packages/directives/__tests__/repeat-click.test.tsx b/packages/directives/__tests__/repeat-click.test.tsx index 7f3f76b56d..299f6d5869 100644 --- a/packages/directives/__tests__/repeat-click.test.tsx +++ b/packages/directives/__tests__/repeat-click.test.tsx @@ -1,13 +1,15 @@ import { mount } from '@vue/test-utils' -import { describe, expect, test, vi } from 'vitest' +import { describe, expect, it, vi } from 'vitest' import sleep from '@element-plus/test-utils/sleep' import RepeatClick from '../repeat-click' -const handler = vi.fn() +let handler: ReturnType + const _mount = () => mount( { setup() { + handler = vi.fn() return () => (
TEST @@ -25,14 +27,40 @@ const _mount = () => ) describe('Directives.vue', () => { - test('Click test', async () => { + it('click test', async () => { const wrapper = _mount() const block = wrapper.find('#block') + block.trigger('mousedown') - const testTime = 330 - await sleep(testTime) - block.trigger('mouseup') - const expectResult = Math.floor(testTime / 100) - expect(handler).toHaveBeenCalledTimes(expectResult) + await sleep(330) + document.dispatchEvent(new MouseEvent('mouseup')) + + expect(handler).toHaveBeenCalledTimes(3) + }) + + it('time interval between mousedown and mouseup is slightly less than 100ms', async () => { + const wrapper = _mount() + const block = wrapper.find('#block') + + for (let i = 0; i < 10; i++) { + block.trigger('mousedown') + await sleep(99) + document.dispatchEvent(new MouseEvent('mouseup')) + } + + expect(handler).toHaveBeenCalledTimes(10) + }) + + it('time interval between mousedown and mouseup is slightly more than 100ms', async () => { + const wrapper = _mount() + const block = wrapper.find('#block') + + for (let i = 0; i < 10; i++) { + block.trigger('mousedown') + await sleep(101) + document.dispatchEvent(new MouseEvent('mouseup')) + } + + expect(handler).toHaveBeenCalledTimes(10) }) }) diff --git a/packages/directives/repeat-click/index.ts b/packages/directives/repeat-click/index.ts index 61808f6528..4f4caa265b 100644 --- a/packages/directives/repeat-click/index.ts +++ b/packages/directives/repeat-click/index.ts @@ -6,22 +6,30 @@ import type { DirectiveBinding, ObjectDirective } from 'vue' export default { beforeMount(el: HTMLElement, binding: DirectiveBinding) { let interval = null - let startTime: number + let isHandlerCalled = false + const handler = () => binding.value && binding.value() + const clear = () => { - if (Date.now() - startTime < 100) { - handler() - } clearInterval(interval) interval = null + + if (!isHandlerCalled) { + handler() + } + isHandlerCalled = false } on(el, 'mousedown', (e: MouseEvent) => { if ((e as any).button !== 0) return - startTime = Date.now() + once(document as any, 'mouseup', clear) + clearInterval(interval) - interval = setInterval(handler, 100) + interval = setInterval(() => { + isHandlerCalled = true + handler() + }, 100) }) }, } as ObjectDirective