chrvadala / react-svg-pan-zoom

:eyes: A React component that adds pan and zoom features to SVG
https://chrvadala.github.io/react-svg-pan-zoom/
MIT License
681 stars 127 forks source link

onClick event is not triggered on svg elements on mobile #81

Open alcalyn opened 6 years ago

alcalyn commented 6 years ago

Actually, I have svg elements on which I can listen to the onClick event.

But this event is no longer triggered once I wrap svg elements into ReactSVGPanZoom.

To test it, just use the onClick event on an svg element, with:

<g onClick={console.log}>
  ...
</g>

Then, on mobile, the event is dispatched on mobile, but it is not when I try to wrap it with ReactSVGPanZoom:

<ReactSVGPanZoom>
  <g onClick={console.log}>
    ...
  </g>
</ReactSVGPanZoom>
alcalyn commented 6 years ago

I could reproduce it on the 1-basic example, with a modification:

https://github.com/alcalyn/react-svg-pan-zoom/pull/1/files

Note: I am using the auto tool

On desktop, the click event is triggered, but not on mobile.

chrvadala commented 6 years ago

I think that the problem is related with some preventDefault that are necessary to avoid some other bug. Can you try to add also a callback onTouchEnd? LMK

alcalyn commented 6 years ago

Yes, here is the jsFiddle: http://jsfiddle.net/f67qyfsd/72/ And for mobile, the embedded version, here is the qrcode: https://duckduckgo.com/?q=qrcode+http%3A%2F%2Fjsfiddle.net%2Ff67qyfsd%2F72%2Fembedded%2F

On desktop, there is onClick event, and on mobile, the onTouchEnd event, at the end of the click or drag.

Dusty4848 commented 5 years ago

The onTouchEnd event did the trick! Thanks

amdufour commented 4 years ago

I had a similar issue and using the touchend event solved it. Thanks!

Tarak-He commented 1 year ago

I came up with a solution to the issue where the onClick event was triggering even when the user was panning the map.

Since setting the tool to "auto" didn't work on mobile, I had to add a new state called touchStartValue. Then, I used the onTouchStart and onTouchEnd events to check whether the user was panning or actually tapping on a path element.

const [touchStartValue, setTouchStartValue] = useState({ e: null, f: null });

<g
  onTouchStart={(e: any) => {
    const tsv = { e: value.e, f: value.f }; // the initial touch start value
    setTouchStartValue(tsv);
  }}
  onTouchEnd={(e: any) => {
    if (touchStartValue.e === value.e && touchStartValue.f === value.f) {
      setShowRegionInfos(e.target.id);
    }
  }}
>

For information, the structure of my component goes like this :

<ReactSVGPanZoom>
  <svg viewBox={`0 0 1366 768`}>
    <g> // ontouchstart and ontouchend events here
      <path /> //clickable element 
      <path /> //clickable element
      <path/> //clickable element 
    </g>
  </svg>
</ReactSVGPanZoom>