2011-03-16 13 views
44

Con Google Maps JS API v3, quiero colocar un marcador donde el usuario hace clic en el mapa, manteniendo el comportamiento predeterminado cuando el usuario hace doble clic (y sin agregar ningún marcador en el mapa).Manejar eventos de clics en Google Maps JS API v3 ignorando clics dobles

Pensé en definir un tiempo de espera en el evento de clic. Si se activa un evento de doble clic dentro de los próximos milisegundos, el tiempo de espera se cancela. Si no, el marcador se coloca en el mapa cuando expira el tiempo de espera. Pero realmente no parece la mejor solución.

¿Hay una forma más elegante de manejar esto?

Gracias.

Respuesta

24

La forma más fácil de resolverlo.

solución
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 es mejor (véase más adelante)

+0

Esta solución no funciona si su función 'placeMarker()' puede ser llamada a veces además de hacer clic en eventos (a menos que siempre llame a 'mapZoom = map.getZoom()' antes de llamar a 'placeMarker() '); Encontré la solución de @ ShogunPanda más flexible en esta circunstancia. –

-4

No estoy seguro, pero si agrega controladores de eventos a los dos eventos 'clic' & 'dblclick', donde dice poner marcador en un clic, y no realiza ninguna acción con doble clic, entonces puede omitir la adición de los tiempos de espera (la API de mapas puede diferenciar lo que es clic y lo que es el doble clic)

google.maps.event.addListener(map, 'click', function (event) { 
     placeMarker(event.latLng); 
    }); 
google.maps.event.addListener(map, 'dblclick', function(event) { 
//DO NOTHING, BECAUSE IT IS DOUBLE CLICK 
}); 

el placemarker (latLng) es la función que añade marcador en el lugar determinado añadió personalizado:

var marker = new google.maps.Marker({ 
     position: location, 
     draggable: true, 
     map: map 
    }); 
map.setCenter(location); 
+3

Gracias por tu respuesta. Pero la API activa un clic y un evento dblclick cuando el usuario hace doble clic:/ – Pierre

7

Puede aprovechar, dblclick incendios si es un Haga doble clic y solo haga clic en los disparos en tales ocasiones una sola vez.

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(); 
}); 

Ver http://www.ilikeplaces.com

+0

¡Funciona muy bien! Si me gusta, tenía que enviar el evento a la función runIfNotDblClick, puede hacer: 'setTimeout (runIfNotDblClick.bind (null, event), 500)' y, por ejemplo, leer latLng en el evento usando 'Array.prototype.slice.call (arguments) [0] .latLng' – riper

58

que acaba de encontrar una solución hacker, que funciona, pero introduce un pequeño tiempo de espera (200 ms, esto es lo mínimo para que funcione, pero Don 't saber si es dependiente del cliente)

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); 
}); 

Espero que esto ayude!

+2

perfecto, gracias! Esta parece la solución menos hortera de los que se ofrecen aquí. – Codemwnci

+0

Esta es la respuesta correcta. – ethmz

+0

Intenté esto, pero no funciona para mí. el primer clic en la doble pulsación borra el tiempo de espera, pero el segundo clic sigue actuando como un clic, y se ejecuta 'do_something_here()'. –

0

Una forma más limpia de implementar el enfoque setTimeout() es activar eventos personalizados para clics individuales.

La siguiente función toma cualquier objeto de la interfaz de Google Maps (por ejemplo, mapa, marcador, polígono, etc.) Y establece dos eventos personalizados:

singleclick: llamados 400ms después de un clic si no hay otros clics han producido

firstclick: llamada cuando se produce un evento de clic, a menos que un clic ya se ha producido en los últimos 400 ms (esto es útil para mostrar algún tipo de información haga clic inmediata al usuario)

function addSingleClickEvents(target) { 
    var delay = 400; 
    var clickTimer; 
    var lastClickTime = 0; 

    google.maps.event.addListener(target, 'click', handleClick); 
    google.maps.event.addListener(target, 'dblclick', handleDoubleClick); 

    function handleClick(e) { 
    var clickTime = +new Date(); 

    var timeSinceLastClick = clickTime - lastClickTime; 

    if(timeSinceLastClick > delay) { 
     google.maps.event.trigger(target, 'firstclick', e); 

     clickTimer = setTimeout(function() { 
     google.maps.event.trigger(target, 'singleclick', e); 
     }, delay); 
    } else { 
     clearTimeout(clickTimer); 
    } 

    lastClickTime = clickTime; 
    } 

    function handleDoubleClick(e) { 
    clearTimeout(clickTimer); 
    lastClickTime = +new Date(); 
    } 
} 

se puede utilizar de este modo:

var map = .... 
addSingleClickEvents(map); 
google.maps.event.addListener(map, 'singleclick', function(event) { 
    console.log("Single click detected at: " + event.latLng); 
} 
3

Si está utilizando underscore.js o * lodash aquí es una forma rápida y elegante de resolver este problema

// 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 se lleva a cabo sólo en lodash (con this commit), underscore.js does not implement it

+0

Esta es de hecho una buena solución. – PureW

+0

Sin embargo, recibo la respuesta 'clickHandler.cancel no es una función' con underscorejs 1.8.3 ... – PureW

+0

@PureW buena captura, funciona solo en lodash. He actualizado la respuesta. – Fabio

Cuestiones relacionadas