2010-12-27 15 views
57

Jestem zajęty skryptem, który zrobi płótno mapy Google na mojej stronie z wieloma znacznikami. Chcę, aby po kliknięciu markera otworzyło się okno informacyjne. Zrobiłem to, a kod jest w tej chwili:Zamknij wszystkie infowindows w 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'); 

To działa w 100%. Ale teraz chcę, aby kiedy jedna infowindow była otwarta, a chcesz otworzyć drugą, pierwsza automatycznie się zamyka. Ale nie znalazłem sposobu, aby to zrobić. infowindow.close(); nie pomoże. Czy ktoś ma przykład lub rozwiązanie tego problemu?

Odpowiedz

123

infowindow jest zmienna lokalna i okna nie jest dostępna w momencie zamknięcia()

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

Dzięki za to. Zmieniłem swój kod z posiadania wielu okien InfoWindows na taki, który zostanie zamknięty/otwarty na każdym marker.click. Działa jak marzenie. – William

+0

@William, czy mógłbyś opublikować fragment kodu z tego, co zrobiłeś i udostępnić go tutaj? – Carl

+1

@Carl zobacz edycję powyżej. Mam nadzieję, że to pomaga. – William

12

Zadeklaruj zmienne globalne:

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

W intialize korzystać z mapy za addEvent metody:

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

Miałem dynamiczną pętlę, która tworzyła infowindows i markery w oparciu o liczbę wprowadzonych danych do CMS, więc nie chciałem tworzyć nowego InfoWindow() na każdym kliknięciu zdarzenia i przechytrzyć go w odpowiedzi na prośby, jeśli kiedykolwiek się pojawiły. Zamiast tego próbowałem się dowiedzieć, jaka konkretna zmienna infowindow dla każdej instancji miała znajdować się poza ustaloną ilością lokalizacji, które miałem, a następnie zachęcam Maps do zamknięcia wszystkich, zanim otworzy się właściwa.

Moja tablica lokalizacjach nazwano lokalizacje, więc PHP skonfigurować przed rzeczywiste mapy initilization aby moje infowindow nazwy zmiennych było:

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

Następnie po initialzing mapę i tak dalej w skrypcie miałem PHP foreach pętlę tworząc informacji dynamicznych okien za pomocą licznika:

//...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... 

Tak, chodzi o to, zanim zadzwoniłem cały skrypt mapę, miałem tablicę z nazwiskami znałem miały być wyprowadzane gdy InfoWindow() został stworzony, jak infowindow0, infowindow1, infowindow2, etc...

Następnie na razie click dla każdego markera , pętla foreach przechodzi i mówi, że zamyka wszystkie z nich przed wykonaniem następnego kroku ich otwierania. Okazuje się, patrząc tak:

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

tylko inny sposób robienia rzeczy przypuszczam ... ale mam nadzieję, że ktoś pomoże.

+2

to straszny kod, żeby go zachować ... dlaczego nie wydrukujesz tablicy json z php i kanałem do kodu javascript –

5

pętle, które tworzy infowindows dynamicznie zadeklarować zmienną globalną

var openwindow;

a następnie w zaproszeniu addListener funkcji (co jest wewnątrz pętli):

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

Czy możesz wyjaśnić cel używania eval tutaj? – AnixPasBesoin

+0

'openwindow' jest ciągiem, jeśli nie używamy eval, instrukcja będzie wykonywana jako' openwindow.close() 'zamiast' myInfoWindow1.close() '. Sprawdź komunikaty o błędach, które tu widzisz: https://jsfiddle.net/ts3z6nw6/1/ – Binod

+0

Moje infowizacje są dodawane przez JS - użyłem tego samego podejścia, deklarując openwindow poza moim forEach(), który tworzy znaczniki z oknami. W moim kodzie nie muszę używać eval, ponieważ openwindow jest już obiektem openwindow. – GuruBob

0

mam coś podobnego do następującego:

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

W moim rozumieniu użycie takiego zamknięcia pozwala na przechwytywanie zmiennych i ich wartości w czasie deklaracji funkcji, a nie poleganie na zmiennych globalnych. Więc kiedy openWindowFn jest wywoływany później, na przykład na pierwszym znaczniku, zmienna content i position ma wartości, które wykonali podczas pierwszej iteracji w funkcji each().

Nie jestem pewien, czy openWindowFn ma w swoim zakresie. Nie jestem też pewien, czy wszystko dobrze działa, ale działa, nawet z wieloma mapami na jednej stronie (każda mapa otrzymuje jedno otwarte informacje).

Jeśli ktoś ma jakiekolwiek spostrzeżenia, prosimy o komentarz.

0

Zachęcam do wypróbowania wtyczki jQuery goMap podczas pracy z Google Maps. Dla tego rodzaju sytuacji można ustawić hideByClick true podczas tworzenia znaczników:

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

To tylko jeden przykład, ma wiele funkcji do zaoferowania jak grupowanie znaczników i manipulacji okna informacyjne.

0

Trzeba kliknąć swoją mapę - $('#map-selector').click();

0

Gdy mamy do czynienia z klastrami znacznik ten pracował dla mnie.

0

Byłem godzinę z bólem głowy próbuje zamknąć infoWindow! Moja ostateczna (i pracy) opcja została zamykając infoWindow z setTimeout (kilka sekund) To nie jest najlepszy sposób ... ale to działa easely

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

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

}); 
0

Mam próbkę mojego kodu, że może może pomóc. Ustawiłem tylko jeden obiekt infowindow w zasięgu globalnym. Następnie użyj setContent(), aby ustawić zawartość przed wyświetleniem.

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); 
     }); 
    }) 
    } 
Powiązane problemy