Google Maps w ukrytym div

Korzystanie z Google Maps JS API v3 dla zamieszczania Google Map na stronie, jest całkiem fajne i proste. Możesz zdecydować czy chcesz dodać jakieś markery, jaką informację powinny zawierać, itd. Ale to już pewnie wiesz, a ten post nie jest o tym jaki świetny jest Google Maps ;o)

W niektórych przypadkach, podejmujemy decyzję aby ukryć diva z mapą w środku. Na przykład w jakiś tabach/zakładkach. Nistety mapa nie jest kompletna kiedy zostaje pokazana i prawdopodobnie wygląda jakoś tak:

broken google map

 

To nie ma tak być. Gdzie jest reszta mapy?

Podstawowy przykład wyświetlania mapy w tym API znajdziesz – jak inaczej – dokumentacji google. I to jest miejsce gdzie większość osób zacznie się uczyć na ten temat.

Wykorzystam podobny przykład, ale wsadzę moją mapę w proste zakładki, które utworzyłam w jQuery. Zobacz przykład ukrytej Google Mapy w tabie online. Nie zapomnij sprawdzić kodu źródłowego, zanim będziesz kontynuował.

Jak widać na przykładzie, kiedy klikniesz na zakładkę „Tab Map” mapa wygląda jakby nie do końca się załadowała. Kod nie różni się od tego z przykładu google. Po prostu ukryłam diva z mapą w zakładce.

Jakie jest rozwiązanie dla tego problemu? Odpowiedź to:

google.maps.event.trigger(map, "resize");

Tak. To wszystko. No… prawie. Musisz wiedzieć gdzie to coś powinno być ;o)

rozwiązanie dla ukrytej mapy

 Dodałam poniższy fragment kodu do zdarzenia click dla mojej zakładki:

if($(this).attr('href')=='#tab2'){
    var center = map.getCenter();
    google.maps.event.trigger(map, "resize");
    map.setCenter(center);
}

Sprawdzam czy użytkownik kliknął na link do zakładki z mapą. Jeśli tak, to mapa powinna dostosować swój rozmiar. ALE! Zamieszczając ten kawałek kodu to za mało. Musisz przenieść var map poza funkcje initialize W ten sposób ze zmiennej lokalnej zmienisz ją w globalną. Jeśli nie wiesz jaka jest różnica między lokalną a globalną zmienną – wyguglaj. To są podstawy. Nie zapomnij usunąć var z funkcji initialize() przy map.

Jest tam jeszcze extra kod dla wyśrodkowywania mapy, który rozwiązuje znany problem po „resize”. Jeśli nie ustalimy na nowo jak mapa ma być wyśrodkowana, wówczas nasz środek będzie w lewym górnym rogu. Należy pobrać koordynaty dla środka przed wywołaniem „resize” dla mapy.

Tada!

Jest jeszcze jedno rozwiązanie. Nie ma takie potrzeby aby inicjować mapę podczas ładowania. Dlaczego nie zrobić tego wtedy, kiedy jest to rzeczywiście potrzebne?

drugie rozwiązanie dla ukrytej mapy

Usunęłam zdarzenie onload z body i przeniosłam initialize() do zdarzenia on click. W ten sposób mapa załaduje się wtedy kiedy rzeczywiście jest potrzebna. Dobrze jest też srawdzić czy do zmiennej map zostało już coś przypisane/zdefiniowane, aby uniknąć ładowania się mapy przy każym kliku.

if($(this).attr('href')=='#tab2' && !map){
    initialize();
}

jQuery.mobile i mapa w ukrytym divie

Jeśli wykorzystuje jQuery mobile, wówczas strony są ładowane/pokazywane za pomocą animacji. Tak więc aby to działało musisz mieć pewność, że „resize” mapy zostanie wykonany PO wykonaniu animacji kiedy div jest w pełni widoczny. W tym celu po prostu dołącz go do zdarzenia pageshow w ten sposób:

$(document).on( "pageshow", function( event, data ){
    var center = map.getCenter();
    google.maps.event.trigger(map, "resize");
    map.setCenter(center);
});

i powinno bez problemu zadziałać. Upewnij się tylko, że zostanie to wywołane już po inicjalizacji mapy. Czyli jeśli mapa jest ładowana w zdarzeniu .load to tam ten fragment kodu też powinien się znaleźć.

Uwaga

To: google.maps.event.trigger(map, „resize”); naprawdę działa. Jeśli nie działa dla ciebie, to znaczy, że robisz coś źle lub gdzie indziej jest coś nie tak. Być może obiekt mapy nie jest dostępny (sprawdź czy jest zmienna globalną) lub zdarzenie „resize” jest wywoływane za wcześnie.