Polymer: preventDefault only works in a tap handler if the source was a click, not a touch

Created on 7 Apr 2016  路  5Comments  路  Source: Polymer/polymer

If you call event.preventDefault() in a tap handler, it will only prevent default if the source event was a click, but not if the source was a touch.

This means that if I have a tap handler on a site with touch input and I want to prevent default, I need to add a touchend handler and call event.preventDefault there. This leads to having two handlers for the same event (a tap and a touchend handler) in many places across the site, which isn't ideal.

In gestures.html (https://github.com/Polymer/polymer/blob/master/src/standard/gestures.html#L395), preventDefault is called for click events only, because for a touch the sourceEvent is Touch (changedTouches[0]) rather than something from the browser's event chain, like touchend.

bug

Most helpful comment

Hi,

Agree with lesliana.
Seems like touch events are fired giving an instance of a Touch object as sourceEvent.
The Touch object has no preventDefault method. Therefore, in the fire method, even if preventDefault is called on a tap event, the original event won't be default prevented.

I have the same issue when I want to prevent default a track event.

Thanks

All 5 comments

Here is a reduced test case: http://jsbin.com/hisozi/3

It appears as though an unchecked ghost click fires on the <a>. The expectation is that this event would be default prevented. However, it appears that it is not being prevented.

Hi,

Agree with lesliana.
Seems like touch events are fired giving an instance of a Touch object as sourceEvent.
The Touch object has no preventDefault method. Therefore, in the fire method, even if preventDefault is called on a tap event, the original event won't be default prevented.

I have the same issue when I want to prevent default a track event.

Thanks

as a workaround

Try to add a touchstart handler to your listener object that has tap or track handlers. You can call preventDefault on the event you receive. This event is the same event that started the tap or the tracking.

    listeners : {
      'touchstart': '_preventDefault',
      'tap': '_tapHandler'
     },

    _preventDefault: function(event) {
      event.preventDefault();
    }

@azakus In the polymer documentation, it says

sourceEvent鈥攖he original DOM event that caused the [...] action

But this is not the case for touch events. Do you think the doc should be changed ? Or maybe the sourceEvent should be the actual event and use another object to get event positions.

I modified the commit so that you get the idea.
https://github.com/hypnoce/polymer/commit/7d3a7e0629e95811aed7c8b194022d1ef93e8634

@azakus is there any movement on this?

Was this page helpful?
0 / 5 - 0 ratings