Обработка событий кликов в JS API Google Maps v3 при игнорировании двойных щелчков
С API Google Maps JS v3, я хочу удалить маркер, где пользователь нажимает на карту, сохраняя поведение по умолчанию, когда пользователь дважды щелкает (и не добавляет маркер на карту).
Я подумал об определении тайм-аута события click. Если в течение нескольких миллисекунд срабатывает событие двойного щелчка, тайм-аут отменяется. Если нет, маркер помещается на карту, когда истекает время ожидания.
Но на самом деле это не похоже на лучшее решение.
Есть ли более элегантный способ справиться с этим?
Спасибо.
Ответы
Ответ 1
Самый простой способ его решить.
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 лучше (см. ниже)
Ответ 2
Я только нашел хакерское решение, которое работает, но введет небольшое время ожидания (200 мс, это минимум, чтобы заставить его работать, но я не знаю, зависит ли он от клиента)
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);
});
Надеюсь, это поможет!
Ответ 3
Вы можете воспользоваться преимуществами dblclick fire, если это двойной щелчок, и один клик в таких случаях срабатывает только один раз.
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();
});
См. http://www.ilikeplaces.com
Ответ 4
Если вы используете underscore.js или * lodash здесь быстрый и элегантный способ решить эту проблему.
// 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 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 реализуется только в lodash (this commit), underscore.js не реализует его
Ответ 5
Более чистый способ реализации подхода setTimeout()
- инициировать пользовательские события для одиночных кликов.
Следующая функция принимает любой объект интерфейса Google Maps (например, карту, маркер, многоугольник и т.д.) и устанавливает два пользовательских события:
singleclick
: называется 400 мс после щелчка, если не произошло никаких других щелчков
firstclick
: вызывается всякий раз, когда происходит событие клика, если только клик уже не произошел за последние 400 мс (это удобно для отображения какой-либо обратной связи с кликом для пользователя)
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();
}
}
Вы можете использовать его так:
var map = ....
addSingleClickEvents(map);
google.maps.event.addListener(map, 'singleclick', function(event) {
console.log("Single click detected at: " + event.latLng);
}
Ответ 6
Я не уверен, но если вы добавите обработчики событий для событий 'click' и 'dblclick', где вы говорите, что нужно нанести маркер на клик и не предпринимать никаких действий при двойном щелчке, вы можете пропустите добавление тайм-аутов (API-интерфейс карт может отличаться от того, что клик и что двойной щелчок)
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
});
PlaceMarker (latLng) - пользовательская добавленная функция, которая добавляет маркер в заданное местоположение:
var marker = new google.maps.Marker({
position: location,
draggable: true,
map: map
});
map.setCenter(location);