Search code examples
javascriptiphonetouchscreen

Button not working properly on iPhone (and possibly other touch screens)


I have a Map-button that you click (or tap) to show a modal with an embedded Google Map. It works like it should on desktop in different browsers, but on iPhone (and possibly other touch screens) I have to tap the button twice.

Edit: Tried using "ontouchend" for trigger and "touchend" for closing the modal. Now the modal closes as soon as it opens.

The HTML:

<div class="map-modal" id="map-modal">
    <div class="map-container">
        <div class="the-map" id="map-canvas"></div>
        <div class="hide-btn hide-btn--map" onclick="closeModal();"><span class="close hairline"></span><div class="hidden-content">Hide the map</div></div>
    </div>
</div>

Button:

<div class="button button--map" onmousedown="calcRoute('<?php echo $location[address1]; ?>', '<?php echo $location[address2]; ?>');">Map</div>

The JavaScript:

function calcRoute(start, end) {
    var e = document.getElementById("map-modal");
    e.style.display = 'block';
    $("body").addClass("modal-open");
    google.maps.event.trigger(map, 'resize');
    var request = {
        origin:start,
        destination:end,
        travelMode: google.maps.TravelMode.WALKING
    };
    directionsService.route(request, function(response, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            directionsDisplay.setDirections(response);
        } else {
            alert("Sorry, no walking route can be found between these locations");
        }
    });
}

google.maps.event.addDomListener(window, 'load', initialize);

Solution

  • Solution (not perfect)

    Solution updated, see below.

    Captured the "second" touch by sending a boolean variable with the trigger event. For ontouchstart set touched=true, for onclick set touched=false. Then in the modal closing function check if there's a touch event, and just reset the touched variable.

    It's not an elegant solution. If the Google Maps logo happens to be where the user touched the screen to open the map, it registers as an extra touch, and the Google Maps application opens.

    The solution is to prevent the event from bubbling up the DOM tree (never heard about event bubbling before myself). Googling and finding this pointed me in the right direction. It's pretty simple. Just use this.stopPropagation(); on the event trigger.

    I kept the previous solution in this post, to show what I tried and to perhaps male it easier to understand how event propagation (or "event bubbling") is working in cases like this.

    If anyone have an even more elegant solution, feel free to share.

    Trigger Event Button

    <div class="button button--map right"
        ontouchstart="this.stopPropagation(); calcRoute('Citybox+Oslo,+Prinsens+gate+6,+0152+Oslo,+Norway', '<?php echo $location[address]; ?>');"
        onclick="calcRoute('Citybox+Oslo,+Prinsens+gate+6,+0152+Oslo,+Norway', '<?php echo $location[address]; ?>');"
        >Map</div>