title: How to prevent default handling of touch events?
body: <p>I am trying to do something similar to what <a href="https://www.embedmap.net/" rel="noreferrer">embedded Google maps</a> do. My component should ignore single touch (allowing user to scroll page) and pinch outside of itself (allowing user to zoom page), but should react to double touch (allowing user to navigate inside the component) and disallow any default action in this case.</p>
  
  <p>How do I prevent default handling of touch events, but only in the case when user is interacting with my component with two fingers?</p>
  
  <p>What I have tried:</p>
  
  <ol>
  <li><p>I tried capturing <code>onTouchStart</code>, <code>onTouchMove</code> and <code>onTouchEnd</code>. It turns out that on FF Android the first event that fires when doing pinch on component is <code>onTouchStart</code> with a single touch, then <code>onTouchStart</code> with two touches, then <code>onTouchMove</code>. But calling <code>event.preventDefault()</code> or <code>event.stopPropagation()</code> in <code>onTouchMove</code> handler doesn't (always) stop page zoom/scroll. Preventing event escalation in the first call to <code>onTouchStart</code> <em>does help</em> - unfortunately at that time I don't know yet if it's going to be multitouch or not, so I can't use this.</p></li>
  <li><p>Second approach was setting <code>touch-action: none</code> on <code>document.body</code>. This works with Chrome Android, but I could only make it work with Firefox Android  if I set this on all elements (except for my component). So while this is doable, it seems like it could have unwanted side effects and performance issues. <strong>EDIT:</strong> Further testing revealed that this works for Chrome only if the CSS is set before the touch has started. In other words, if I inject CSS styles when I detect 2 fingers then <code>touch-action</code> is ignored. So this is not useful on Chrome.</p></li>
  <li><p>I have also tried adding a new event listener on component mount:</p>
  
  <pre><code>document.body.addEventListener("touchmove", ev =&gt; {
    ev.preventDefault();
    ev.stopImmediatePropagation();
  }, true);
  </code></pre>
  
  <p>(and the same for <code>touchstart</code>). Doing so works in Firefox Android, but does nothing on Chrome Android.</p></li>
  </ol>
  
  <p>I am running out of ideas. Is there a reliable cross-browser way to achieve what Google apparently did, or did they use multiple hacks and lots of testing on every browser to make it work? I would appreciate if someone pointed out an error in my approach(es) or propose a new way.</p>