Вкладка переключения данных не загружает карту Leaflet

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


Код Navbar:

<ul class="nav nav-tabs">
    <li class="active"><a data-toggle="tab" href="#home">Données principales</a></li>
    <li><a data-toggle="tab" href="#carte">Carte</a></li>
</ul>
<div class="tab-content">
    <div id="home" class="tab-pane fade in active">Lorem ipsum</div>
    <div id="carte" class="tab-pane fade"> **//see script below\\** </div>
</div>

Сценарий:

<div id="carteBenef"></div>
      <script type="text/javascript">
          $(document).ready(function () {
              var map = new L.Map('carteBenef');
              var cloudmadeUrl = 'http://{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png',
                     subDomains = ['otile1', 'otile2', 'otile3', 'otile4'],
                     cloudmadeAttrib = 'Data, imagery and map information provided by <a href="http://open.mapquest.co.uk" target="_blank">MapQuest</a>, <a href="http://www.openstreetmap.org/" target="_blank">OpenStreetMap</a> and contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/" target="_blank">CC-BY-SA</a>';
              var cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18, attribution: cloudmadeAttrib, subdomains: subDomains});
              var iades = new L.LatLng(<?php echo $beneficiaire->latitude . ', ' . $beneficiaire->longitude; ?>)
              map.addLayer(cloudmade).setView(iades, 15);
              var benefLocation = new L.LatLng(<?php echo $beneficiaire->latitude . ', ' . $beneficiaire->longitude; ?>);
              var benef = new L.Marker(benefLocation);
              map.addLayer(benef);
              benef.bindPopup("<?php echo htmlspecialchars($beneficiaire->nom) . ' ' . htmlspecialchars($beneficiaire->prenom); ?>").openPopup();
          });
      </script>

Карта появлялась задолго до того, как я положил ее на вкладку, у кого-нибудь есть идея, почему она сейчас не работает? Спасибо =)

3 ответа

Решение

Добро пожаловать на ТАК!

Если ваша карта Leaflet неожиданно работает правильно после изменения размера окна браузера, тогда вы испытываете классический "размер контейнера карты, недопустимый при инициализации карты": для правильной работы Leaflet считывает размер контейнера карты при инициализации карты (L.map("mapContainerId")).

Если ваше приложение скрывает этот контейнер (обычно через CSS display: none; или какая-либо структура вкладки / модал / что угодно...) или позже изменяет свои размеры, Leaflet не будет знать о новом размере. Следовательно, он не будет отображаться правильно. Как правило, он загружает плитки только для той части контейнера, которая, по его мнению, отображается. Это может быть одна плитка в верхнем левом углу в случае контейнера, который был полностью скрыт во время инициализации карты.

Эта ошибка часто возникает при встраивании контейнера карты в "вкладку" или "модальную" панель, возможно, с использованием популярных фреймворков (Bootstrap, Angular, Ionic и т. Д.).

Leaflet прослушивает событие изменения размера окна браузера и снова считывает размер контейнера, когда это происходит. Это объясняет, почему карта внезапно работает при изменении размера окна.

Вы также можете вручную запустить это обновление, позвонив map.invalidateSize() когда отображается панель вкладок (например, добавьте слушателя при нажатии кнопки вкладки), по крайней мере, при первом отображении контейнера с его правильными размерами.

Что касается реализации прослушивателя щелчка по кнопке вкладки, выполните новый поиск в SO по этой теме: у вас должно быть достаточно ресурсов для этого, для большинства популярных фреймворков.

Во-первых, спасибо @ghybs за хорошее объяснение того, почему карты Leaflet не отображаются должным образом в этих случаях.

Для тех, кто безуспешно пытался ответить на @ ghybs, вы должны попытаться изменить размер своего браузера вместо вызова метода объекта карты:

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

Это исправление сработало для меня, и оно должно работать во всех случаях.

Для тех, кто, как я, не смог решить проблему с драгоценным объяснением @ghybs (map.invalidateSize()) и смогли сделать это с помощью @gangai-johann one, все еще есть шанс, что вы сделаете это правильно. Поместите вашу инструкцию недействительной в setTimeout, так как может быть слишком рано отправлять эту инструкцию.

setTimeout(() => {
    this.$refs.mymap.mapObject.invalidateSize()
}, 100)

Обратитесь к /questions/48454255/karta-vue2-listovki-ne-otobrazhaetsya-dolzhnyim-obrazom-v-modalnosti-boostrapvue/48454273#48454273 ответ для получения подробных инструкций.

У меня есть эта проблема, потому что я использовал modal bootstarp. и это не решено в любом случае. Я старался map.invalidateSize() а также window.dispatchEvent(new Event('resize')); но не исправлено.

наконец это исправлено этим:

$('#map-modal').on('shown.bs.modal', function(event) {});

'shown.bs.modal' Событие означает, что модальный режим полностью загружен, а не какой-либо путаницы по размеру, теперь внутри пишут ваши коды.

Другие вопросы по тегам