admin管理员组

文章数量:1180452

I am creating a custom calendar in React.js which has a date range selection functionality.

It works perfectly on desktop. On mobile, when i touch the date cell and try to drag, the screen start scrolling. But i want to disable the scroll when the user is dragging but also allow user to scroll when the user does the scroll gesture on the scroll. I have already tried using touch-action: none on the date cell, but it completely disables the scroll. For your information i am using pointer events to handle both mouse and touch

So i tried to apply touch-action: none dynamically, with the help of setTimeout.

const isDraggingRef = useRef<boolean>(false)

const handlePointerDown = (event: React.PointerEvent, date: string) => {
  
// Initialize drag-related state
  dragStartRef.current = date;
  dragEndRef.current = date;

// Add pointermove and pointerup listeners globally
  document.addEventListener("pointermove", handleMouseMoveGlobal);
  document.addEventListener("pointerup", handlePointerUpGlobal);

  pointerTimeoutRef.current = setTimeout(() => {
  isDraggingRef.current = true;
  }, 200); // Adjust the timeout as needed
};

When the isDraggingRef is true, touch-action: none is applied dynamically. But the interesting thing is as soon as pointer down event runs, the pointer cancel event runs (i read somewhere if scroll is not disabled initially, the pointer events conflict with other browser events and pointer events get cancelled) and it does not reach the pointerUp event callback (it contains logic for setting the range on pointer up). So as pointerup is not called, the range doesn't get selected. Note that range does get selected on 2nd attempt as isDraggingRef.current is still true and touch-action: none is already active.

Also i got to know that onTouchStart if i do event.preventDefault(), it will disable the scroll. Here also i will have to do it dynamically, as i want scroll to be there when user is not trying to drag and select. But here also it did not work on 1st attempt (as pointerCancel runs as soon as pointer down runs and it never reaches the pointerUp.

Airbnb has this functionality done already. Attaching a screenshot from their site

本文标签: javascriptDisable Scrolling While Dragging in a Mobile Reactjs ApplicationStack Overflow