как работать с картой Google внутри скрытого div (обновленное изображение)


127

У меня есть страница, и карта Google сначала находится внутри скрытого div. Затем я показываю div после того, как нажимаю ссылку, но отображается только верхний левый угол карты.

Я попытался запустить этот код после щелчка:

    map0.onResize();

или:

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

Любые идеи. вот изображение того, что я вижу после показа div со скрытой картой в нем.альтернативный текст


По этому поводу уже есть ряд вопросов, включая отображение карты Google из скрытой области
Мэтт Болл,

@Matt Ball - после обновления я попытался добавить туда событие изменения размера, но все еще не работает
leora

@ Мэтт Болл - я заставил это работать. после того, как я создаю объект карты Google, я сохраняю его в глобальной переменной, чтобы я мог ссылаться на него позже, и теперь вызов изменения размера, похоже, работает. Я стараюсь не воссоздавать объект карты каждый раз, когда я его показываю, потому что я позволяю людям переключаться вперед и назад.
leora 01

@ooo, это очень просто с кодом ниже. Все, что вам нужно добавить, - это условие if, чтобы проверить, инициализирован ли объект карты или нет. Это был нестандартный код, написанный для решения вашей первоначальной проблемы, заключающейся в правильной загрузке карты.
Филар 01

@philar - ага. , спасибо здесь. , таким образом, голос за :). В любом случае мне нужно хранить переменные на глобальном уровне, чтобы избежать
повторной

Ответы:


103

Просто протестировал сам, и вот как я к этому подошел. Довольно просто, дайте мне знать, если вам нужны пояснения

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>

Итак, в основном вы создаете экземпляр карты только тогда, когда отображается div? Есть ли способ сделать это, чтобы объект карты создавался только один раз (при загрузке страницы)?
Лукас

1
Я также мог бы предложить задержку setTimeout для вызова второй функции, если вы вызываете show (), чтобы дать время на изменение размера.
Эрик, 18

126

У меня была такая же проблема, и я обнаружил, что при отображении div вызывается, google.maps.event.trigger(map, 'resize');и, похоже, это решает проблему для меня.


64
Чтобы сохранить исходный центр карты сразу после изменения размера, рассмотрите возможность расширения оператора изменения размера следующим образом: var center = map.getCenter (); google.maps.event.trigger (карта, «изменить размер»); map.setCenter ( в центре);
Джон Доппельманн,

10
Не знаю почему, но мне нужно заключить решение в небольшой setTimeout, чтобы заставить его работать: setTimeout (function () {google.maps.event.trigger (map, 'resize')}, 100);
HoffZ

@JohnDoppelmann Спасибо за подсказку! Было не интуитивно понятно, почему он не поддерживает центр или как заставить его вернуться.
Ной Дункан

Снова установите центр карты и уровень масштабирования после запуска события изменения размера. Для получения дополнительной информации см .: code.google.com/p/gmaps-api-issues/issues/detail?id=1448
ruhong

@HoffZ это, вероятно, связано с тем, что ваш код изменения размера запускается перед эффектом показа, тайм-аут задерживает его до тех пор, пока шоу не будет выполнено, затем изменение размера может заставить его работать. Вероятно, вы можете добиться того же эффекта, изменив порядок выполнения кода, чтобы гарантировать, что при запуске события отображение div выполняется до изменения размера карты.
Бардо

26
google.maps.event.trigger($("#div_ID")[0], 'resize');

Если у вас нет доступной карты переменных, это должен быть первый элемент (если вы не сделали что-то глупое) в divэлементе, содержащем GMAP.


Вы уверены, что можете запускать элемент в div вместо объекта google.map.Map ?
Salman A

@SalmanA - Только что проверил, и у меня это сработало (хотя на карте, похоже, есть новый центр). Из предыдущего исследования я тоже не знал, что это возможно, так что слава CSN
Hal

CS N ... Это работает для меня, но оставляет центральное положение не в том месте. Моя карта инициализируется, как снимок экрана OP, и это похоже на центр: он находится в верхнем левом углу моего map_canvas. Мысли о том, как заставить рисовать по центру?
Кирк Росс

13

У меня была карта Google внутри вкладки Bootstrap, которая не отображалась правильно. Это было моим исправлением.

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

1
Мне пришлось заменить «показано» на «показано.bs.tab», чтобы это работало для карты, которая была скрыта на неактивной вкладке. Спасибо
Никола

Я использую SmartWizard 4, и это единственное решение, которое сработало для меня, и оно сработало отлично! Я изменил 'a[href="#profileTab"]'на step-2который имя DIV , содержащего карту DIV.
GeospatialPython.com

7

Как обновить карту при изменении размера div

Недостаточно просто позвонить google.maps.event.trigger(map, 'resize');Вам следует также сбросить центр карты.

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

Как прослушивать событие изменения размера

Угловой (коллапс ng-show или ui-bootstrap)

Привяжите напрямую к видимости элемента, а не к значению, привязанному к ng-show, потому что $ watch может сработать до обновления ng-show (так что div по-прежнему будет невидимым).

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

jQuery .show ()

Используйте встроенный обратный вызов

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

Bootstrap 3 Modal

$('#myModal').on('shown.bs.modal', function() {
    resize();
})

ваш метод модального изменения размера bootstrap 3 отлично устранил мою проблему, тогда как большинство других предложений - нет. Спасибо!
BrianLegg

6

Если у вас есть карта Google, вставленная путем копирования / вставки кода iframe, и вы не хотите использовать API Карт Google , это простое решение. Просто выполните следующую строку javascript, когда вы показываете скрытую карту. Он просто берет HTML-код iframe и вставляет его в то же место, поэтому он снова отображается:

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

версия jQuery:

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

HTML:

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

Следующий пример работает для карты, изначально скрытой на вкладке Bootstrap 3:

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

2
Лучшее решение для тех, кто не загружает Google Map JS, а просто использует iframe с URL-адресом srchttps://www.google.com/maps/embed/v1/place?..
gsinha

6

Также возможно просто вызвать собственное событие изменения размера окна.

Карты Google перезагрузятся автоматически:

window.dispatchEvent(new Event('resize'));

5

У меня была такая же проблема, у google.maps.event.trigger(map, 'resize')меня не работало.

Я установил таймер для обновления карты после того, как стал видимым 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(....
    ....
}

Не знаю, удобнее ли это сделать, но он работает!


используйте setTimeout, чтобы подождать один раз.
Джо Остин

4

С jQuery вы можете сделать что-то вроде этого. Это помогло мне загрузить карту Google в Umbraco CMS на вкладке, которая не была видна сразу.

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

waitForVisibleMapElement();

Это единственное решение, которое помогло мне и моей проблеме. У меня была карта Google внутри вкладки Materialize.CSS, которая не отображала карту, а показывала только серый фон с только маркером и логотипом Google в левом углу. Я установил div содержимого вкладки для инициализации карты, когда она видна, и она отлично работает. Пример
Gorgon_Union 09

3

Мое решение очень простое и эффективное:

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


2

Я предполагаю, что исходный вопрос связан с картой, которая инициализируется в скрытом div страницы. Я решил аналогичную проблему, изменив размер карты в скрытом div после того, как документ будет готов, после его инициализации, независимо от его статуса отображения. В моем случае у меня есть 2 карты, одна отображается, а другая скрыта при их инициализации, и я не хочу инициализировать карту каждый раз, когда она отображается. Это старый пост, но я надеюсь, что он поможет всем, кто ищет.


2

Я обнаружил, что это работает для меня:

прятаться:

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

показывать:

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

2

При использовании внутри вкладок Bootstrap v3 должно работать следующее:

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

где tab-location- идентификатор вкладки, содержащей карту.


2

Как указали Джон Доппельманн и HoffZ, соберите весь код вместе, как показано ниже, в вашем div, показывающем функцию или событие onclick:

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

У меня это сработало отлично


0

Мое решение было:

CSS:

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

JQuery:

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

0

Мне не нравилось, что карта загружалась только после того, как скрытый div стал видимым. Например, в карусели это не работает.

Это мое решение - добавить класс к скрытому элементу, чтобы отобразить его и вместо этого скрыть с абсолютным положением, затем отобразить карту и удалить класс после загрузки карты.

Протестировано в Bootstrap Carousel.

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

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

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

0

Первый пост. Мой div googleMap находился внутри контейнера div с {display: none}, пока не была нажата вкладка. Была та же проблема, что и OP. Это сработало для меня:

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

Вставьте этот код внутрь и в конец вашего кода, где щелкнули вкладку вашего контейнера div и открыли ваш скрытый div. Важно то, что div вашего контейнера должен быть видимым до того, как будет вызвана инициализация.

Я попробовал ряд решений, предложенных здесь и на других страницах, и они не помогли мне. Сообщите мне, работает ли это для вас. Спасибо.


0

Добавьте этот код перед div или передайте его в файл js:

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

Это событие будет инициировано после загрузки div, поэтому оно обновит содержимое карты без необходимости нажимать F5.


0

После отображения карты я геокодирую адрес, а затем устанавливаю центр карты. У google.maps.event.trigger(map, 'resize');меня не сработало.

Мне пришлось использовать map.setZoom(14);

Код ниже:

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

            }
        });

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.