useMobileTouchMove.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import { onBeforeUnmount, watch, onMounted } from 'vue';
  2. const SMOOTH_PTG = 14 / 15;
  3. export default function useMobileTouchMove(inVirtual, listRef, callback) {
  4. let touched = false;
  5. let touchY = 0;
  6. let element = null;
  7. // Smooth scroll
  8. let interval = null;
  9. const cleanUpEvents = () => {
  10. if (element) {
  11. element.removeEventListener('touchmove', onTouchMove);
  12. element.removeEventListener('touchend', onTouchEnd);
  13. }
  14. };
  15. const onTouchMove = e => {
  16. if (touched) {
  17. const currentY = Math.ceil(e.touches[0].pageY);
  18. let offsetY = touchY - currentY;
  19. touchY = currentY;
  20. if (callback(offsetY)) {
  21. e.preventDefault();
  22. }
  23. // Smooth interval
  24. clearInterval(interval);
  25. interval = setInterval(() => {
  26. offsetY *= SMOOTH_PTG;
  27. if (!callback(offsetY, true) || Math.abs(offsetY) <= 0.1) {
  28. clearInterval(interval);
  29. }
  30. }, 16);
  31. }
  32. };
  33. const onTouchEnd = () => {
  34. touched = false;
  35. cleanUpEvents();
  36. };
  37. const onTouchStart = e => {
  38. cleanUpEvents();
  39. if (e.touches.length === 1 && !touched) {
  40. touched = true;
  41. touchY = Math.ceil(e.touches[0].pageY);
  42. element = e.target;
  43. element.addEventListener('touchmove', onTouchMove, {
  44. passive: false
  45. });
  46. element.addEventListener('touchend', onTouchEnd);
  47. }
  48. };
  49. const noop = () => {};
  50. onMounted(() => {
  51. document.addEventListener('touchmove', noop, {
  52. passive: false
  53. });
  54. watch(inVirtual, val => {
  55. listRef.value.removeEventListener('touchstart', onTouchStart);
  56. cleanUpEvents();
  57. clearInterval(interval);
  58. if (val) {
  59. listRef.value.addEventListener('touchstart', onTouchStart, {
  60. passive: false
  61. });
  62. }
  63. }, {
  64. immediate: true
  65. });
  66. });
  67. onBeforeUnmount(() => {
  68. document.removeEventListener('touchmove', noop);
  69. });
  70. }