web-dev-qa-db-ja.com

Google Maps API v3のすべての情報ウィンドウを閉じます

私は自分のウェブサイトに複数のマーカーでグーグルマップキャンバスを作成するスクリプトで忙しいです。マーカーをクリックすると、情報ウィンドウが開きます。私はそれをしました、そしてコードは今のところです:

 var latlng = new google.maps.LatLng(-34.397, 150.644);
    var myOptions = {
      zoom: 8,
      center: latlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    function addMarker(map, address, title) {
     geocoder = new google.maps.Geocoder();
     geocoder.geocode( { 'address': address}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
          map.setCenter(results[0].geometry.location);
          var marker = new google.maps.Marker({
     position: results[0].geometry.location,
              map: map,
              title:title
    });
    google.maps.event.addListener(marker, 'click', function() {
     var infowindow = new google.maps.InfoWindow();
            infowindow.setContent('<strong>'+title + '</strong><br />' + address);
             infowindow.open(map, marker);

          });
        } else {
          alert("Geocode was not successful for the following reason: " + status);
        }
     });
    }
    addMarker(map, 'Address', 'Title');
 addMarker(map, 'Address', 'Title');

これは100%機能します。しかし、今では、1つの情報ウィンドウが開いているときに、2番目の情報ウィンドウを開くと、最初のウィンドウが自動的に閉じます。しかし、私はそれを行う方法を見つけていません。 infowindow.close();助けにはなりません。誰かがこの問題の例や解決策を持っていますか?

66
Tom

infowindowはローカル変数であり、close()の時点ではウィンドウは使用できません

var latlng = new google.maps.LatLng(-34.397, 150.644);
var infowindow = null;

...

google.maps.event.addListener(marker, 'click', function() {
    if (infowindow) {
        infowindow.close();
    }
    infowindow = new google.maps.InfoWindow();
    ...
});
...
144

グローバル変数を宣言します。

var mapOptions;
var map;
var infowindow;
var marker;
var contentString;
var image;

intializeで、マップのaddEventメソッドを使用します。

google.maps.event.addListener(map, 'click', function() {
    if (infowindow) {
        infowindow.close();
    }
});
14
user1834631

infowindowsを動的に作成するループの場合、グローバル変数を宣言します

var openwindow;

そして、addListenerfunction呼び出し(ループ内):

google.maps.event.addListener(marker<?php echo $id; ?>, 'click', function() {
if(openwindow){
    eval(openwindow).close();
}
openwindow="myInfoWindow<?php echo $id; ?>";
myInfoWindow<?php echo $id; ?>.open(map, marker<?php echo $id; ?>);
});
6
Binod

CMSへの入力数に基づいてinfowindowsとマーカーを作成する動的ループがあったので、イベントのクリックと沼地ごとに新しいInfoWindow()を作成したくありませんでしたそれが発生した場合、それはリクエストでダウンします。代わりに、各インスタンスの特定のinfowindow変数が設定した場所の範囲外になることを確認し、正しい場所を開く前にそれらをすべて閉じるようにマップを要求しました。

私の場所の配列は場所と呼ばれたので、PHP私はbeforeを設定しましたinfowindow変数名を取得するための実際のマップの初期化は次のとおりです。

_for($k = 0; $k < count($locations); $k++) {
        $infowindows[] = 'infowindow' . $k; 
} 
_

次に、マップの初期化などを行った後、スクリプトでPHP foreachループを使用して、カウンターを使用して動的情報ウィンドウを作成しました。

_//...javascript map initilization
<?php 
$i=0;
foreach($locations as $location) {

    ..//get latitudes, longitude, image, etc...

echo 'var mapMarker' . $i . ' = new google.maps.Marker({
          position: myLatLng' . $i . ',
          map: map,
          icon: image
      });';

echo 'var contentString' . $i . ' = "<h1>' . $title[$i] . '</h1><h2>' . $address[$i] . '</h2>' . $content[$i] .         '";'; 
echo 'infowindow' . $i . ' = new google.maps.InfoWindow({ ';
echo '    content: contentString' . $i . '
          });';

echo 'google.maps.event.addListener(mapMarker' . $i . ', "click", function() { ';   
    foreach($infowindows as $window) {  
        echo $window . '.close();'; 
    }
        echo 'infowindow' . $i . '.open(map,mapMarker'. $i . ');
      });';

$i++; 
}
?>
...//continue with Maps script... 
_

したがって、ポイントは、マップスクリプト全体を呼び出す前に、InfoWindow()が作成されたときに_infowindow0, infowindow1, infowindow2, etc..._のように出力されるとわかっていた名前の配列があったことです。

次に、各マーカーのclickイベントで、foreachループが実行され、次のステップを開く前にすべてを閉じるように指示されます。次のようになります。

_google.maps.event.addListener(mapMarker0, "click", function() {
    infowindow0.close();
    infowindow1.close();
    infowindow2.close();
    infowindow0.open(map,mapMarker0);
}
_

ただ違うやり方をするだけだと思う​​が...誰かに役立つことを願っている。

1
RCNeil

マップをクリックする必要があります-$('#map-selector').click();

0
Slava

マーカークラスターを扱うとき、これは私のために働いた。

var infowindow = null;

google.maps.event.addListener(marker, "click", function () {

        if (infowindow) {
            infowindow.close();
        }
        var markerMap = this.getMap();
        infowindow = this.info;
        this.info.open(markerMap, this);


    });
0
Daniel Badro

私は次のようなものを持っています

function initMap()
{
    //...create new map here
    var infowindow;
    $('.business').each(function(el){
        //...get lat/lng
        var position = new google.maps.LatLng(lat, lng);
        var content = "contents go here";
        var title = "titleText";
        var openWindowFn;
        var closure = function(content, position){.
            openWindowFn = function()
            {
                if (infowindow)
                {
                    infowindow.close();
                }
                infowindow = new google.maps.InfoWindow({
                    position:position,
                    content:content
                });
                infowindow.open(map, marker);
            }
        }(content, position);
        var marker = new google.maps.Marker({
            position:position,
            map:map,
            title:title.
        });
        google.maps.event.addListener(marker, 'click', openWindowFn);
    }
}

私の理解では、そのようなクロージャーを使用すると、グローバル変数に依存するのではなく、関数宣言時に変数とその値をキャプチャできます。したがって、たとえば最初のマーカーでopenWindowFnが後で呼び出された場合、contentおよびposition変数は、each() 関数。

openWindowFnのスコープにinfowindowがどのように含まれているのか、本当にわかりません。また、私が正しいことをしているかどうかはわかりませんが、1ページに複数のマップがある場合でも機能します(各マップは1つの情報ウィンドウを開きます)。

誰にも洞察があれば、コメントしてください。

0
rwilson04

役立つコードのサンプルがあります。グローバルスコープで情報ウィンドウオブジェクトを1つだけ設定しました。次に、コンテンツを表示する前にsetContent()を使用してコンテンツを設定します。

  let map;
  let infowindow;
  let dataArr = [
    {
      pos:{lat: -34.397, lng: 150.644},
      content: 'First marker'
    },
    {
      pos:{lat: -34.340, lng: 150.415},
      content: 'Second marker'
    }
  ];

  function initMap() {
    map = new google.maps.Map(document.getElementById('map'), {
      center: {lat: -34.397, lng: 150.644},
      zoom: 8
    });
    // Set infowindow object to global varible
    infowindow = new google.maps.InfoWindow();
    loadMarker();
  }

  function loadMarker(){
    dataArr.forEach((obj, i)=>{
      let marker = new google.maps.Marker({
        position: obj.pos,
        map: map
      });
      marker.addListener('click', function() {
        infowindow.close()
        infowindow.setContent(`<div> ${obj.content} </div>`)
        infowindow.open(map, marker);
      });
    })
  }
0
Joe

Googleマップを使用する場合は、 goMap jQueryプラグインを試すことをお勧めします。このような状況では、マーカーを作成するときにhideByClickをtrueに設定できます。

$(function() { 
    $("#map").goMap({ 
        markers: [{  
            latitude: 56.948813, 
            longitude: 24.704004, 
            html: { 
                content: 'Click to marker', 
                popup:true 
            } 
        },{  
            latitude: 54.948813, 
            longitude: 21.704004, 
            html: 'Hello!' 
        }], 
        hideByClick: true 
    }); 
}); 

これはほんの一例であり、マーカーのグループ化や情報ウィンドウの操作など、多くの機能を備えています。

0
Steamer

InfoWindowを閉じようとして頭痛で1時間かかりました!私の最後の(そして機能する)オプションは、SetTimeout(数秒)でinfoWindowを閉じることです。これは最良の方法ではありません...しかし、簡単に動作します

    marker.addListener('click', function() {
    infowindow.setContent(html);
    infowindow.open(map, this);

    setTimeout(function(){
        infowindow.close();
    },5000);

});
0
gtamborero