Wie gehe ich mit Google Map in einem versteckten Div um? (Aktualisiertes Bild)

127

Ich habe eine Seite und eine Google Map befindet sich zunächst in einem versteckten Div. Ich zeige dann das Div, nachdem ich auf einen Link geklickt habe, aber nur oben links auf der Karte wird angezeigt.

Ich habe versucht, diesen Code nach dem Klick auszuführen:

    map0.onResize();

oder:

  google.maps.event.trigger(map0, 'resize')

irgendwelche Ideen. Hier ist ein Bild von dem, was ich sehe, nachdem ich das Div mit der versteckten Karte darin gezeigt habe.Alt-Text

Leora
quelle
Es gibt bereits eine Reihe von Fragen zu SO, einschließlich der Google-Kartenanzeige aus einem versteckten Bereich
Matt Ball
@ Matt Ball - wie aktualisiert, ich habe versucht, das Größenänderungsereignis dort hinzuzufügen, aber immer noch nicht funktioniert
Leora
@ Matt Ball - ich habe das zum Laufen gebracht. Nachdem ich das Google Map-Objekt erstellt habe, speichere ich es in einer globalen Variablen, damit ich später darauf verweisen kann, und der Aufruf von resize scheint jetzt zu funktionieren. Ich versuche, das Kartenobjekt nicht jedes Mal neu erstellen zu müssen, wenn ich es zeige, weil ich es den Leuten erlaube, hin und her zu wechseln.
Leora
@ooo das ist sehr einfach mit dem Code unten. Sie müssen lediglich eine if-Bedingung hinzufügen, um zu überprüfen, ob das Kartenobjekt initialisiert wurde oder nicht. Dies war ein Off-the-Cuff-Code, der geschrieben wurde, um Ihr anfängliches Problem zu lösen, nämlich das korrekte Laden der Karte.
Philar
@philar - yup. . danke hier. . also das upvote :). In
beiden Fällen muss

Antworten:

103

Habe es einfach selbst getestet und hier ist, wie ich es angegangen bin. Ziemlich einfach, lassen Sie mich wissen, wenn Sie eine Klarstellung benötigen

HTML

<div id="map_canvas" style="width:700px; height:500px; margin-left:80px;" ></div>
<button onclick="displayMap()">Show Map</button>

CSS

<style type="text/css">
#map_canvas {display:none;}
</style>

Javascript

<script>
function displayMap()
{
    document.getElementById( 'map_canvas' ).style.display = "block";
    initialize();
}
function initialize()
{
    // create the map
    var myOptions = {
        zoom: 14,
        center: new google.maps.LatLng( 0.0, 0.0 ),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    map = new google.maps.Map( document.getElementById( "map_canvas" ),myOptions );
}
</script>
Philar
quelle
Im Grunde genommen initialisieren Sie die Karte also nur, wenn das Div angezeigt wird? Gibt es eine Möglichkeit, dies zu tun, damit das Kartenobjekt nur einmal instanziiert wird (beim Laden der Seite)?
Lucas
1
Ich könnte auch eine setTimeout-Verzögerung vorschlagen, um die zweite Funktion aufzurufen, wenn Sie eine show () aufrufen, um Zeit für die Größenänderung zu haben.
Eric.18
126

Ich hatte das gleiche Problem und stellte fest, dass beim Anzeigen des Div der Anruf google.maps.event.trigger(map, 'resize');das Problem für mich zu lösen scheint.

Eric
quelle
64
Erweitern Sie die Größenänderungsanweisung folgendermaßen, um die ursprüngliche Mitte der Karte direkt nach der Größenänderung beizubehalten: var center = map.getCenter (); google.maps.event.trigger (map, 'resize'); map.setCenter (Mitte);
John Doppelmann
10
Ich weiß nicht warum, aber ich muss die Lösung in ein kleines setTimeout einbinden, damit es funktioniert: setTimeout (function () {google.maps.event.trigger (map, 'resize')}, 100);
HoffZ
@ JohnDoppelmann Danke für den Tipp! Es war nicht intuitiv, warum es das Zentrum nicht aufrechterhielt oder wie man es zurückzwang.
Noah Duncan
Stellen Sie die Kartenmitte und die Zoomstufe erneut ein, nachdem Sie das Ereignis "Größe ändern" ausgelöst haben. Weitere Informationen finden Sie unter: code.google.com/p/gmaps-api-issues/issues/detail?id=1448
ruhong
@HoffZ Dies liegt wahrscheinlich daran, dass Ihr Größenänderungscode vor dem Show-Effekt ausgelöst wird. Das Timeout verzögert ihn, bis die Show ausgeführt wird. Dann kann die Größenänderung funktionieren. Sie können wahrscheinlich den gleichen Effekt erzielen, indem Sie die Ausführungsreihenfolge Ihres Codes ändern, um sicherzustellen, dass beim Auslösen des Ereignisses die div-Anzeige ausgeführt wird, bevor die Kartengröße geändert wird.
Bardo
26
google.maps.event.trigger($("#div_ID")[0], 'resize');

Wenn Sie keine Variablenzuordnung zur Verfügung haben, sollte dies das erste Element in divGMAP sein (es sei denn, Sie haben etwas Dummes getan) .

CSN
quelle
Sind Sie sicher, dass Sie ein Element in einem div anstelle eines google.map.Map- Objekts auslösen können ?
Salman A
@ SalmanA - Habe das gerade überprüft und es hat bei mir funktioniert (obwohl die Karte ein neues Zentrum zu haben scheint). Von früheren Forschungen wusste ich nicht, dass dies auch möglich ist, also ein großes Lob an CSN
Hal
CS N ... Das funktioniert bei mir, aber die Mittelposition bleibt an der falschen Stelle. Meine Karte wird wie der Screenshot des OP initialisiert und ist wie die Mitte: zentriert sich in der oberen linken Ecke meiner map_canvas. Gedanken darüber, wie man es zentriert zeichnen lässt?
Kirk Ross
13

Ich hatte eine Google-Karte in einem Bootstrap-Tab, die nicht richtig angezeigt wurde. Das war mein Fix.

// Previously stored my map object(s) in googleMaps array

$('a[href="#profileTab"]').on('shown', function() {   // When tab is displayed...
    var map = googleMaps[0],
        center = map.getCenter();
    google.maps.event.trigger(map, 'resize');         // fixes map display
    map.setCenter(center);                            // centers map correctly
});
Simon East
quelle
1
Ich musste "gezeigt" durch "gezeigt.bs.tab" ersetzen, damit dies für eine Karte funktioniert, die in einem inaktiven Tab versteckt war. Vielen Dank
Nicola
Ich verwende SmartWizard 4 und dies ist die einzige Lösung, die für mich funktioniert hat und die großartig funktioniert hat! Ich habe den Namen des DIV geändert 'a[href="#profileTab"]', step-2der die Karte DIV enthält.
GeospatialPython.com
7

So aktualisieren Sie die Karte, wenn Sie die Größe Ihres Div ändern

Es reicht nicht aus, nur anzurufen. google.maps.event.trigger(map, 'resize');Sie sollten auch die Mitte der Karte zurücksetzen.

var map;

var initialize= function (){
    ...
}

var resize = function () {
    if (typeof(map) == "undefined") {) {
        // initialize the map. You only need this if you may not have initialized your map when resize() is called.
        initialize();
    } else {
        // okay, we've got a map and we need to resize it
        var center = map.getCenter();
        google.maps.event.trigger(map, 'resize');
        map.setCenter(center);
    }
}

So warten Sie auf das Größenänderungsereignis

Winkel (ng-show oder ui-bootstrap kollabieren)

Binden Sie direkt an die Sichtbarkeit des Elements und nicht an den Wert, der an ng-show gebunden ist, da die $ watch ausgelöst werden kann, bevor die ng-show aktualisiert wird (sodass das div weiterhin unsichtbar ist).

scope.$watch(function () { return element.is(':visible'); },
    function () {
        resize();
    }
);

jQuery .show ()

Verwenden Sie den eingebauten Rückruf

$("#myMapDiv").show(speed, function() { resize(); });

Bootstrap 3 Modal

$('#myModal').on('shown.bs.modal', function() {
    resize();
})
civmeup
quelle
Ihre modale Größenänderungsmethode für Bootstrap 3 hat mein Problem perfekt behoben, während die meisten anderen Vorschläge dies nicht taten. Vielen Dank!
BrianLegg
6

Wenn Sie eine Google Map durch Kopieren / Einfügen des Iframe-Codes eingefügt haben und die Google Maps-API nicht verwenden möchten , ist dies eine einfache Lösung. Führen Sie einfach die folgende Javascript-Zeile aus, wenn Sie die versteckte Karte anzeigen. Es wird nur der iframe-HTML-Code genommen und an derselben Stelle eingefügt, sodass er erneut gerendert wird:

document.getElementById("map-wrapper").innerHTML = document.getElementById("map-wrapper").innerHTML;

jQuery-Version:

$('#map-wrapper').html( $('#map-wrapper').html() );

Der HTML:

....
<div id="map-wrapper"><iframe src="https://www.google.com/maps/..." /></div>
....

Das folgende Beispiel funktioniert für eine Karte, die ursprünglich auf einer Registerkarte "Bootstrap 3" ausgeblendet war:

<script>
$(document).ready( function() {

    /* Detects when the tab is selected */
    $('a[href="#tab-id"]').on('shown.bs.tab', function() {

        /* When the tab is shown the content of the wrapper
           is regenerated and reloaded */

        $('#map-wrapper').html( $('#map-wrapper').html() ); 

    });
});
</script>
Gustavo
quelle
2
Beste Lösung für alle, die nicht Google Map JS laden, sondern einfach iframe mit src urlhttps://www.google.com/maps/embed/v1/place?..
gsinha
6

Es ist auch möglich, einfach das native Fenstergrößenänderungsereignis auszulösen.

Google Maps lädt sich automatisch neu:

window.dispatchEvent(new Event('resize'));
Philip
quelle
5

Ich hatte das gleiche Problem, das google.maps.event.trigger(map, 'resize')funktionierte nicht für mich.

Was ich getan habe, war einen Timer zu setzen, um die Karte zu aktualisieren, nachdem die div...

//CODE WORKING

var refreshIntervalId;

function showMap() {
    document.getElementById('divMap').style.display = '';
    refreshIntervalId = setInterval(function () { updateMapTimer() }, 300);
}

function updateMapTimer() {
    clearInterval(refreshIntervalId);
    var map = new google.maps.Map(....
    ....
}

Ich weiß nicht, ob es der bequemere Weg ist, aber es funktioniert!

Carlos
quelle
Verwenden Sie setTimeout, um einmal zu warten.
Joe Austin
4

Mit jQuery können Sie so etwas tun. Dies hat mir geholfen, eine Google Map in Umbraco CMS auf eine Registerkarte zu laden, die nicht sofort sichtbar ist.

function waitForVisibleMapElement() {
    setTimeout(function () {
        if ($('#map_canvas').is(":visible")) {
            // Initialize your Google Map here
        } else {
            waitForVisibleMapElement();
        };
    }, 100);
};

waitForVisibleMapElement();
Dennis
quelle
Dies ist die einzige Lösung, die für mich und mein Problem funktioniert hat. Ich hatte eine Google-Karte in einem Materialise.CSS-Tab, auf der die Karte nicht angezeigt wurde, sondern nur ein grauer Hintergrund mit nur dem Marker und dem Google-Logo in der linken Ecke. Ich habe die Registerkarte div div so eingestellt, dass die Karte initialisiert wird, wenn sie sichtbar ist, und sie funktioniert einwandfrei. Beispiel
Gorgon_Union
3

Meine Lösung ist sehr einfach und effizient:

HTML

<div class="map-wrap"> 
  <div id="map-canvas"></div>
</div>


CSS

.map-wrap{
  height:0;
  width:0;
  overflow:hidden;
}


Jquery

$('.map-wrap').css({ height: 'auto', width: 'auto' }); //For showing your map
$('.map-wrap').css({ height: 0, width: 0 }); //For hiding your map
Midishero
quelle
2

Ich denke, die ursprüngliche Frage bezieht sich auf eine Karte, die in einem versteckten Teil der Seite initialisiert ist. Ich habe ein ähnliches Problem gelöst, indem ich die Größe der Karte im ausgeblendeten Bereich geändert habe, sobald das Dokument fertig ist, nachdem es initialisiert wurde, unabhängig von seinem Anzeigestatus. In meinem Fall habe ich 2 Karten, eine wird angezeigt und eine wird ausgeblendet, wenn sie initialisiert werden, und ich möchte nicht jedes Mal eine Karte initialisieren, wenn sie angezeigt wird. Es ist ein alter Beitrag, aber ich hoffe, er hilft jedem, der sucht.

KYLO
quelle
2

Ich habe festgestellt, dass dies für mich funktioniert:

verstecken:

$('.mapWrapper')
.css({
  visibility: 'hidden',
  height: 0
});

zeigen:

    $('.mapWrapper').css({
      visibility: 'visible',
      height: 'auto'
    });
Victor S.
quelle
2

Bei Verwendung in Bootstrap v3-Registerkarten sollte Folgendes funktionieren:

$('a[href="#tab-location"]').on('shown.bs.tab', function(e){
    var center = map.getCenter();
    google.maps.event.trigger(map, 'resize');
    map.setCenter(center);
});

Wo tab-locationist die ID der Registerkarte, die die Karte enthält?

Nirmal
quelle
2

Wie John Doppelmann und HoffZ angegeben haben, setzen Sie den gesamten Code wie folgt in Ihrer Div-Show-Funktion oder Ihrem Onclick-Ereignis zusammen:

setTimeout(function(){
var center = map.getCenter();
google.maps.event.trigger(map, 'resize');
map.setCenter(center);
});

Es hat perfekt für mich funktioniert

Victor Tarango
quelle
0

Meine Lösung war:

CSS:

.map {
   height: 400px;
   border: #ccc solid 1px;
}

jQuery:

$('.map').width(555); // width of map canvas
user2385294
quelle
0

Ich mochte es nicht, dass die Karte erst geladen wurde, nachdem das versteckte Div sichtbar geworden war. In einem Karussell zum Beispiel funktioniert das nicht wirklich.

Diese Lösung besteht darin, dem ausgeblendeten Element eine Klasse hinzuzufügen, um es einzublenden und stattdessen mit der absoluten Position auszublenden. Anschließend wird die Karte gerendert und die Klasse nach dem Laden der Karte entfernt.

Im Bootstrap-Karussell getestet.

HTML

<div class="item loading"><div id="map-canvas"></div></div>

CSS

.loading { display: block; position: absolute; }

JS

$(document).ready(function(){
    // render map //
    google.maps.event.addListenerOnce(map, 'idle', function(){
        $('.loading').removeClass('loading');
    });
}

quelle
0

Verwenden Sie diese Codezeile, wenn Sie eine Karte anzeigen möchten.

               $("#map_view").show("slow"); // use id of div which you want to show.
                    var script = document.createElement("script");
                    script.type = "text/javascript";
                    script.src = "https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=initialize";
                    document.body.appendChild(script);
Ravi Darji
quelle
0
 $("#map_view").show("slow"); // use id of div which you want to show.
     var script = document.createElement("script");
     script.type = "text/javascript";
     script.src = "https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=initialize";
     document.body.appendChild(script);
Ravi Darji
quelle
0

Erster Beitrag. Mein googleMap div befand sich in einem Container div mit {display: none}, bis auf die Registerkarte geklickt wurde. Hatte das gleiche Problem wie OP. Das hat bei mir funktioniert:

google.maps.event.addDomListener(window, 'load', setTimeout(initialize, 1));

Stecken Sie diesen Code in und am Ende Ihres Codes, wo auf die Registerkarte "Container-Div" geklickt wird und Ihr verstecktes Div angezeigt wird. Wichtig ist, dass Ihr Container-Div sichtbar sein muss, bevor die Initialisierung aufgerufen werden kann.

Ich habe eine Reihe von hier und auf anderen Seiten vorgeschlagenen Lösungen ausprobiert und sie haben bei mir nicht funktioniert. Lassen Sie mich wissen, ob dies für Sie funktioniert. Vielen Dank.

Leonard
quelle
0

Fügen Sie diesen Code vor dem div hinzu oder übergeben Sie ihn an eine js-Datei:

<script>
    $(document).on("pageshow","#div_name",function(){
       initialize();
    });

   function initialize() {
   // create the map

      var myOptions = {
         zoom: 14,
         center: new google.maps.LatLng(0.0, 0.0),
         mapTypeId: google.maps.MapTypeId.ROADMAP
      }
      map = new google.maps.Map(document.getElementById("div_name"), myOptions);
   }


</script>

Dieses Ereignis wird nach dem Laden des Div ausgelöst, sodass der Karteninhalt aktualisiert wird, ohne dass F5 gedrückt werden muss

Balibrera
quelle
0

Beim Anzeigen der Karte geokodiere ich eine Adresse und setze dann das Kartenzentrum. Das google.maps.event.trigger(map, 'resize');hat bei mir nicht funktioniert.

Ich musste ein verwenden map.setZoom(14);

Code unten:

document.getElementById('map').style.display = 'block';
var geocoder = new google.maps.Geocoder();
        geocoder.geocode({ 'address': input.value }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                map.setCenter(results[0].geometry.location);
                var marker2 = new google.maps.Marker({
                    map: map,
                    position: results[0].geometry.location
                });
                map.setZoom(14);
                marker2.addListener('dragend', function (event) {
                    $('#lat').val(event.latLng.lat());
                    $('#lng').val(event.latLng.lng());
                });

            }
        });
Andrew
quelle
-1

function init_map() {
  var myOptions = {
    zoom: 16,
    center: new google.maps.LatLng(0.0, 0.0),
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  map = new google.maps.Map(document.getElementById('gmap_canvas'), myOptions);
  marker = new google.maps.Marker({
    map: map,
    position: new google.maps.LatLng(0.0, 0.0)
  });
  infowindow = new google.maps.InfoWindow({
    content: 'content'
  });
  google.maps.event.addListener(marker, 'click', function() {
    infowindow.open(map, marker);
  });
  infowindow.open(map, marker);
}
google.maps.event.addDomListener(window, 'load', init_map);

jQuery(window).resize(function() {
  init_map();
});
jQuery('.open-map').on('click', function() {
  init_map();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src='https://maps.googleapis.com/maps/api/js?v=3.exp'></script>

<button type="button" class="open-map"></button>
<div style='overflow:hidden;height:250px;width:100%;'>
  <div id='gmap_canvas' style='height:250px;width:100%;'></div>
</div>

user6414609
quelle