index.ts 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import { useEventListener } from "@vueuse/core";
  2. import type { Directive, DirectiveBinding } from "vue";
  3. import { subBefore, subAfter, isFunction } from "@pureadmin/utils";
  4. export const longpress: Directive = {
  5. mounted(el: HTMLElement, binding: DirectiveBinding<Function>) {
  6. const cb = binding.value;
  7. if (cb && isFunction(cb)) {
  8. let timer = null;
  9. let interTimer = null;
  10. let num = 500;
  11. let interNum = null;
  12. const isInter = binding?.arg?.includes(":") ?? false;
  13. if (isInter) {
  14. num = Number(subBefore(binding.arg, ":"));
  15. interNum = Number(subAfter(binding.arg, ":"));
  16. } else if (binding.arg) {
  17. num = Number(binding.arg);
  18. }
  19. const clear = () => {
  20. if (timer) {
  21. clearTimeout(timer);
  22. timer = null;
  23. }
  24. if (interTimer) {
  25. clearInterval(interTimer);
  26. interTimer = null;
  27. }
  28. };
  29. const onDownInter = (ev: PointerEvent) => {
  30. ev.preventDefault();
  31. if (interTimer === null) {
  32. interTimer = setInterval(() => cb(), interNum);
  33. }
  34. };
  35. const onDown = (ev: PointerEvent) => {
  36. clear();
  37. ev.preventDefault();
  38. if (timer === null) {
  39. timer = isInter
  40. ? setTimeout(() => {
  41. cb();
  42. onDownInter(ev);
  43. }, num)
  44. : setTimeout(() => cb(), num);
  45. }
  46. };
  47. // Register using addEventListener on mounted, and removeEventListener automatically on unmounted
  48. useEventListener(el, "pointerdown", onDown);
  49. useEventListener(el, "pointerup", clear);
  50. useEventListener(el, "pointerleave", clear);
  51. } else {
  52. throw new Error(
  53. '[Directive: longpress]: need callback and callback must be a function! Like v-longpress="callback"'
  54. );
  55. }
  56. }
  57. };