Handling click events in Google Maps JS API v3 while ignoring double clicks

68,185

Solution 1

The easiest way to solve it.

var location;
var map = ...

google.maps.event.addListener(map, 'click', function(event) {
    mapZoom = map.getZoom();
    startLocation = event.latLng;
    setTimeout(placeMarker, 600);
});

function placeMarker() {
    if(mapZoom == map.getZoom()){
        new google.maps.Marker({position: location, map: map});
    }
}

shogunpanda's solution is better (see below)

Solution 2

I just found an hackish solution which works but introduce a small waiting time (200ms, this is the minimum to make it work, but I don't know if it is client dependent)

var update_timeout = null;

google.maps.event.addListener(map, 'click', function(event){
    update_timeout = setTimeout(function(){
        do_something_here();
    }, 200);        
});

google.maps.event.addListener(map, 'dblclick', function(event) {       
    clearTimeout(update_timeout);
});

Hope this helps!

Solution 3

You can take advantage of, dblclick fires if it is a double click, and single click fires in such occations only once.

runIfNotDblClick = function(fun){
    if(singleClick){
        whateverurfunctionis();
    }
};

clearSingleClick = function(fun){
    singleClick = false;
};

singleClick = false;

google.maps.event.addListener(map, 'click', function(event) {// duh! :-( google map zoom on double click!
    singleClick = true;
    setTimeout("runIfNotDblClick()", 500);
});

google.maps.event.addListener(map, 'dblclick', function(event) {// duh! :-( google map zoom on double click!
     clearSingleClick();
});

See http://www.ilikeplaces.com

Solution 4

If you're using underscore.js or* lodash here's a quick and elegant way to solve this problem

// callback is wrapped into a debounce function that is called after
// 400 ms are passed, it provides a cancel function that can be used
// to stop it before it's actually executed
var clickHandler = _.debounce(function(evt) {
  // code called on single click only, delayed by 400ms
  // adjust delay as needed.
  console.debug('Map clicked with', evt);
}, 400);
// configure event listeners for map
google.maps.event.addListener(map, 'click', clickHandler);
google.maps.event.addListener(map, 'dblclick', clickHandler.cancel);

* Debounce.cancel is implemented only in lodash (with this commit), underscore.js does not implement it

Share:
68,185

Related videos on Youtube

Pierre
Author by

Pierre

Hum. No, really nothing interesting for the moment...

Updated on May 24, 2020

Comments

  • Pierre
    Pierre almost 4 years

    With the Google Maps JS API v3, I want to drop a marker where the user clicks on the map, while keeping the default behavior when the user double clicks (and not adding any marker on the map).

    I thought about defining a timeout on click event. If a double click event is triggered within the next few milliseconds, the timeout is cancelled. If not, the marker is placed on the map when the timeout expires. But it doesn't really look like the best solution ever.

    Is there a more elegant way to handle this?

    Thanks.

  • Pierre
    Pierre about 13 years
    Thanks for your answer. But the API triggers both a click and a dblclick event when the user double clicks :/
  • Quinn Comendant
    Quinn Comendant almost 9 years
    This solution doesn't work if your placeMarker() function may be called sometimes besides on click events (unless you always call mapZoom = map.getZoom() before you call placeMarker()); I found @ShogunPanda's solution more flexible in this circumstance.
  • Luis A. Florit
    Luis A. Florit over 8 years
    I tried this, but does not work for me. the first click in the doubleclick clears the timeout, but the second click still acts as a click, and do_something_here() is executed.
  • Luis A. Florit
    Luis A. Florit over 8 years
    Yet, setting a global variable doubleClicked = true in dblclick function and checking for it inside update_timeout solved the issue. ;)
  • riper
    riper over 6 years
    Works great! If you like me had to send the event to runIfNotDblClick function you can do: setTimeout(runIfNotDblClick.bind(null, event), 500) and for example read latLng in event using Array.prototype.slice.call(arguments)[0].latLng