web-dev-qa-db-ja.com

ダブルクリックを無視しながらGoogle Maps JS API v3でクリックイベントを処理する

Google Maps JS API v3では、ユーザーが地図をクリックした場所にマーカーをドロップしますが、ユーザーがダブルクリックしたときのデフォルトの動作を維持します(地図にマーカーを追加しません)。

クリックイベントのタイムアウトを定義することを考えました。次の数ミリ秒以内にダブルクリックイベントがトリガーされると、タイムアウトはキャンセルされます。そうでない場合、マーカーは、タイムアウトの期限が切れたときにマップ上に配置されます。しかし、これは今までで最高のソリューションのようには見えません。

これを処理するよりエレガントな方法はありますか?

ありがとう。

46
Pierre

それを解決する最も簡単な方法。

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 のソリューションの方が優れています(以下を参照)

27
rebeliagamer

動作するハッキングの解決策を見つけましたが、短い待機時間を導入します(200ms、これが動作するための最小値ですが、クライアントに依存するかどうかはわかりません)

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

お役に立てれば!

62
ShogunPanda

ダブルクリックの場合はdblclickが起動し、そのような場所ではシングルクリックが1回だけ起動します。

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 を参照してください

7

使用している場合 nderscore.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 実装しない

3
Fabio

setTimeout()アプローチを実装するよりクリーンな方法は、シングルクリックに対してカスタムイベントをトリガーすることです。

次の関数は、Googleマップのインターフェースオブジェクト(地図、マーカー、ポリゴンなど)を取り、2つのカスタムイベントを設定します。

singleclick:他のクリックが発生していない場合、クリック後に400ms呼び出されます

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