index.ts 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import { isFunction } from '@element-plus/utils'
  2. import type { ObjectDirective } from 'vue'
  3. export const REPEAT_INTERVAL = 100
  4. export const REPEAT_DELAY = 600
  5. export interface RepeatClickOptions {
  6. interval?: number
  7. delay?: number
  8. handler: (...args: unknown[]) => unknown
  9. }
  10. export const vRepeatClick: ObjectDirective<
  11. HTMLElement,
  12. RepeatClickOptions | RepeatClickOptions['handler']
  13. > = {
  14. beforeMount(el, binding) {
  15. const value = binding.value
  16. const { interval = REPEAT_INTERVAL, delay = REPEAT_DELAY } = isFunction(
  17. value
  18. )
  19. ? {}
  20. : value
  21. let intervalId: ReturnType<typeof setInterval> | undefined
  22. let delayId: ReturnType<typeof setTimeout> | undefined
  23. const handler = () => (isFunction(value) ? value() : value.handler())
  24. const clear = () => {
  25. if (delayId) {
  26. clearTimeout(delayId)
  27. delayId = undefined
  28. }
  29. if (intervalId) {
  30. clearInterval(intervalId)
  31. intervalId = undefined
  32. }
  33. }
  34. el.addEventListener('mousedown', (evt: MouseEvent) => {
  35. if (evt.button !== 0) return
  36. clear()
  37. handler()
  38. document.addEventListener('mouseup', () => clear(), {
  39. once: true,
  40. })
  41. delayId = setTimeout(() => {
  42. intervalId = setInterval(() => {
  43. handler()
  44. }, interval)
  45. }, delay)
  46. })
  47. },
  48. }