2011-03-16 58 views
44

使用Google Maps JS API v3,我想在用戶點擊地圖時放置一個標記,同時保持用戶雙擊時的默認行爲(和不在地圖上添加任何標記)。在Google Maps JS API v3中處理點擊事件,同時忽略雙擊

我想過點擊事件定義超時。如果在接下來的幾毫秒內觸發雙擊事件,超時將被取消。如果沒有,則當超時到期時,標記將被放置在地圖上。但它看起來並不像有史以來最好的解決方案。

有沒有更好的方法來處理這個問題?

謝謝。

回答

24

解決這個問題最簡單的方法。

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的解決方案是更好的(見下文)

+0

如果你的'placeMarker()'函數有時候除了點擊事件(除非在調用'placeMarker()之前總是調用'mapZoom = map.getZoom()'''''' ');我發現@ ShogunPanda的解決方案在這種情況下更加靈活。 – 2015-06-17 00:13:12

-4

我不確定,但是如果您將事件處理程序添加到'點擊'&'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); 
+3

感謝您的回答。但是,當用戶雙擊時,API會觸發點擊和dblclick事件:/ – Pierre 2011-03-17 10:32:36

7

您可以利用,如果它是一個dblclick火災雙擊,並單擊一次在這種情況下觸發。

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

+0

很棒!如果你喜歡我不得不將事件發送到runIfNotDblClick函數,你可以這樣做:'setTimeout(runIfNotDblClick.bind(null,event),500)',例如使用'Array.prototype.slice.call(arguments)讀取latLng事件。 [0] .latLng' – riper 2018-01-07 22:41:18

58

我只是找到了一個hackish的解決方案,它工作,但推出更小型的等待時間(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); 
}); 

希望這有助於!

+2

完美,謝謝!這似乎是這裏提供的最不俗的解決方案。 – Codemwnci 2011-12-22 17:23:32

+0

這是正確的答案。 – ethmz 2015-09-05 22:39:23

+0

我試過這個,但不適合我。雙擊的第一次點擊清除超時,但第二次點擊仍然是點擊,並執行'do_something_here()'。 – 2015-10-29 00:02:37

0

實現setTimeout()方法的更簡潔方法是觸發自定義事件以進行單擊。

以下函數使用任何Google Maps界面對象(例如地圖,標記,多邊形等)),並設置了兩個自定義事件:

singleclick:所謂的400毫秒點擊後,如果沒有其他的點擊行爲發生

firstclick:所謂只要點擊事件發生時,除非點擊在過去的400ms的已經發生(這是非常方便的顯示某種直接點擊反饋給用戶)

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

如果您使用 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'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僅在lodash實現(與this commit),underscore.js does not implement it

+0

這確實是一個不錯的解決方案。 – PureW 2016-05-22 23:56:35

+0

但是,我得到的響應'clickHandler.cancel不是一個函數'與下劃線1.8.3 ... – PureW 2016-05-23 00:04:53

+0

@PureW好抓,它只適用於lodash。我已經更新了答案。 – Fabio 2016-05-23 20:01:43

相關問題