ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
50.94k stars 13.52k forks source link

bug: mousedown and mouseup event not fired #2614

Closed amazaud closed 9 years ago

amazaud commented 9 years ago

Type: bug

Platform: mobile webview

When using Google Maps API binded to a ion-content with data-tap-disabled="false", the mousedown and mouseup event are not sent to GMaps if it happens 2 seconds after another one.

After having looked into the ionic code, it seems that it after receiving a touchstart or touchend event, it prevents the mousedown and mouseup event for the 2 next seconds by calling a function named tapEnableTouchEvents (line 2781 of ionic.bundle.js from 1.0.0-beta13). As a result, when tapping on a mobile app, the touchstart and mousedown event are sent, but if ending the tap less than 2 seconds after having starting it, only the touchend event is fired and the mouseup event had been prevented by ionic.

As all of this is done within the ionic EventListener functions directly binded to DOM Events, it does not check the value of "data-tap-disabled" element attribute and always prevent the mousedown and mouseup event.

This could be an issue in some usage scenario. For example, when integrating Google Maps API in a ionic app and registering mousedown and mouseup event on google.maps.Map object to place a marker on the map after having pressed the map for one second, as the first mousedown event is sent, the marker is placed even if the map had been pressed for less than 1 sec. Another resulting issue is that it is impossible to place another marker less than 2 seconds after a first one since the mousedown event will not be propagated.

Here is a codepen example illustrating the problem: http://codepen.io/adrien-mazaud/pen/MYwObz

In that codepen, when google.maps.Map object receive a "mousedown" event, it start a timeout of one second (using angular's $timeout service) that will execute a function placing a marker on the map and save the promise returned by $timeout. Then, when it receive a "mouseup" event, it will used the saved $timeout promise if exists in order to cancel it ($timeout.cancel(promise)). The expected behavior is to place a marker on the map when pressing it for at least 1 second or do nothing otherwise.

It is interesting to note that this issue happens only on mobile device or using Chrome DevTools with "device mode" enabled (by clicking the phone icon on the top-left corner of DevTools and then reloading page). When trying on a desktop computer browser, it works perfectly.

Please also note that google.maps.Map object in that codepen is binded to an ion-content element with "data-tap-disabled" attribute set to false, but removing that attribute does not change anything.

Lastly, registering "touchstart" and "touchend" event could be a workaround in some scenario, but it does not work in this particular scenario since Google Maps API since to not forward the "touch" event to integrators listeners functions.

The following issue had been created after having discussed that problem on ionic's forum. More information about this issue may be found at http://forum.ionicframework.com/t/tap-event-with-google-maps-api-not-received/13245

alexjoverm commented 9 years ago

It's happening to me too. Hope to find a solution

BarryReid commented 9 years ago

I am getting the same problem. Please fix

kashban commented 9 years ago

I am getting it too, though not while using Google API but a jQuery Slider Plugin called ion.RangeSlider.

mhartington commented 9 years ago

So the issue with the google maps from @amazaud is due to binding to the ion-content. Switching it out to another element gets rid of the issue.

http://codepen.io/mhartington/pen/YPJZmE