IOS HTML disable double tap to zoom

28,981

Solution 1

The CSS property touch-action works for me. Tested on iOS 11.1.

button {
    touch-action: manipulation;
}

See MDN for more info: https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action

Solution 2

I ended up solving this problem by using the following code: See Greg's answer above

$(document).click(function(event) {
    element = document.elementFromPoint(event.clientX, event.clientY);
    if(document.getElementById("div_excluded_from_doubletap").contains(element)) {
        event.preventDefault();
        clickFunction(element);
    }
});

Solution 3

I made a bit of a complicated answer, but it works very well and reliably at stopping double-tap and pinch-to-zoom and allows pretty much every other kind of interaction

let drags = new Set() //set of all active drags
document.addEventListener("touchmove", function(event){
  if(!event.isTrusted)return //don't react to fake touches
  Array.from(event.changedTouches).forEach(function(touch){
    drags.add(touch.identifier) //mark this touch as a drag
  })
})
document.addEventListener("touchend", function(event){
  if(!event.isTrusted)return
  let isDrag = false
  Array.from(event.changedTouches).forEach(function(touch){
    if(drags.has(touch.identifier)){
      isDrag = true
    }
    drags.delete(touch.identifier) //touch ended, so delete it
  })
  if(!isDrag && document.activeElement == document.body){
    //note that double-tap only happens when the body is active
    event.preventDefault() //don't zoom
    event.stopPropagation() //don't relay event
    event.target.focus() //in case it's an input element
    event.target.click() //in case it has a click handler
    event.target.dispatchEvent(new TouchEvent("touchend",event))
    //dispatch a copy of this event (for other touch handlers)
  }
})

note: greg's answer does not work consistently (double-tapping on certain elements will still zoom)

If you want to prevent pinch-to-zoom, you'll need some JS and CSS (don't ask me why):

document.addEventListener('touchmove', function(event){
  if (event.scale !== 1) event.preventDefault(); //if a scale gesture, don't
})

and

*{touch-action: pan-x pan-y} /*only allow scroll gestures*/
Share:
28,981
tchatow
Author by

tchatow

Updated on March 26, 2021

Comments

  • tchatow
    tchatow about 3 years

    I am designing a website primarily focused on data entry. In one of my forms I have buttons to increment and decrement the number value in a form field quickly. I was using

    <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    

    to disable the zoom which appeared to work using the Firefox app for IOS. However, when another user tested it with Safari, clicking on the button too fast resulted in zooming in on the page, distracting the user and making it impossible to increase the value quickly. It appears that as of IOS 10, apple removed user-scalable=no for accessibility reasons, so that's why it only works in 3rd party browsers like Firefox. The closest I found to disabling double tap zoom was this

    var lastTouchEnd = 0;
    document.addEventListener('touchend', function (event) {
        var now = (new Date()).getTime();
        if (now - lastTouchEnd <= 300) {
            event.preventDefault();
        }
        lastTouchEnd = now;
    }, false);
    

    from https://stackoverflow.com/a/38573198 However, this disables quickly tapping altogether, which although prevents double tap zooming, also prevents the user from entering values quickly. Is there any way to allow a button to be pressed quickly, while also disabling double tap zooming?

  • tchatow
    tchatow over 6 years
    In my question, I have already stated that I am using this code. However, as of IOS 10, Safari no longer applies user-scalable=no for accessibility reasons.
  • Danial
    Danial over 6 years
    This also works in 10.2.1. Putting it on 'body' pretty much disables it overall.
  • Pier
    Pier over 6 years
    This did it for me alongside the viewport meta for disabling zoom.
  • stealthwang
    stealthwang about 6 years
    this only works for block level elements / elements with known height & widths. inline elements will still have the default browser touch behaviors.
  • tchatow
    tchatow about 6 years
    Thanks! This seems to work a lot better than the solution I came up with earlier.
  • Ion
    Ion about 3 years
    Works in iOS 14.4
  • David Vielhuber
    David Vielhuber over 2 years
    Does not work in 14.3 and 15.0 for certain elements. jsbin.com/sizavudima/edit?html,output