I use Hammer.js to detect touches on mobile devices, tap, swipe etc.
I have an interaction where on tap, i hide the tapped content (and possibly parents) and show some other content in its place (change screen - like functionality).
The problem is that the newly visible contents may have events of their own binded on them, or may natively interact on tap (eg labels toggling checkboxes, text inputs being focused). If the components are hidden/displayed as soon as tap occurs, the 400ms click event is still running and is then triggered on the elements below.
Check out this jsfiddle on mobile:
http://jsfiddle.net/annam/xGJZL/
http://jsfiddle.net/annam/xGJZL/embedded/result/
<div class="checkbox">
<input type="checkbox" id="check" />
<label for="check"></label>
</div>
<div class="box"></div>
<style>
.checkbox { width: 500px; height: 500px; position: absolute; top: 0; ; left: 0; }
.checkbox input { display: none; }
.checkbox label { display: block; width: 100%; height: 100%; background: yellow; }
.checkbox input:checked + label { background: green; }
.box { position: absolute; top: 0; left: 0; width: 200px; height: 200px; background: pink; }
</style>
<script>
$('.box').hammer().on('tap', function(e){ $(this).hide(); })
$('label').hammer().on('tap', function(e){ $('.box').show(); })
</script>
Check out how on tap, the label below is toggled (MOBILE ONLY!). This doesn't happen on the web, it happens because a native click event is triggered on the label because it's visible on the tap position within 400ms of the touchstart event.
Also try to change the tap event on the label to a native click event. This is also incorrectly triggered (MOBILE ONLY!).
Other instances I've noticed this happen other than click events and labels is input fields, where the text input field is focused (and keyboard pops up) as soon as it is displayed behind the tap event.
Using preventDefault and stopPropagation does not fix this issue as it's not an issue with event bubbling, and the event that is prevented is actually "tap", where as we need to stop is something in the range of click/mousedown/touch. This seems to happen with both hammerjs v1 and v2 (v1 with e.gesture.preventDefault()
etc doesn't work either).
Any way to avoid this?