You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Maps API问题:第二个标签页地图无法显示求助

解决Google Maps在隐藏标签页中无法正常显示的问题

嗨,我帮你找到了问题的根源啦!当页面加载时,第二个地图的容器#mapEtranger是被CSS设置为display: none的状态,而Google Maps API在初始化地图时,需要读取容器的实际尺寸(宽高)来正确渲染地图。隐藏元素的尺寸会被计算为0,这就导致第二个地图初始化失败,切换标签后自然显示不正常。

下面是具体的修复方案,我会一步步帮你调整代码:

核心思路

我们不在页面加载时就初始化所有地图,而是切换到对应的标签页时,才初始化该标签页的地图(如果还没初始化过),这样就能保证初始化时地图容器是可见的,API能正确获取尺寸。

修改后的完整代码

HTML部分(和原代码基本一致,无需改动)

<div class="tab_map">
  <button id="defaultOpen" class="tablinks_map" onclick="openMap(event, 'France')">ETA en France</button>
  <button class="tablinks_map" onclick="openMap(event, 'Etranger')">ETA à l'étranger</button>
</div>

<div id="France" class="tabcontent_map">
  <div id="mapFrance"></div>
</div>

<div id="Etranger" class="tabcontent_map">
  <div id="mapEtranger"></div>
</div>

<script async defer src='https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=init'></script>

CSS部分(原代码无需改动)

#mapFrance {
  height: 700px;
  width: 100%;
}

#mapEtranger {
  height: 700px;
  width: 100%;
}

/* Style the tab */
.tab_map {
  overflow: hidden;
  border: 1px solid #ccc;
  background-color: #f1f1f1;
}

/* Style the buttons that are used to open the tab content */
.tab_map button {
  background-color: inherit;
  float: left;
  border: none;
  outline: none;
  cursor: pointer;
  padding: 14px 16px;
  transition: 0.3s;
  color: black;
}

/* Change background color of buttons on hover */
.tab_map button:hover {
  background-color: #ddd;
}

/* Create an active/current tablink class */
.tab_map button.active {
  background-color: #ccc;
}

/* Style the tab content */
.tabcontent_map {
  display: none;
  padding: 6px 12px;
  border: 1px solid #ccc;
  border-top: none;
  -webkit-animation: fadeEffect 1s;
  animation: fadeEffect 1s;
}

JavaScript部分(关键修改在这里)

// 用来存储已初始化的地图,避免重复初始化
const initializedMaps = {};
const centre_france = { lat: 46.599923, lng: 2.432420 };

// 初始化法国地图的函数
function initMapFrance() {
  const mapFrance = new google.maps.Map(document.getElementById('mapFrance'), {
    zoom: 6,
    center: centre_france
  });

  const locationsFrance = [
    ['Bureaux à Plérin', 48.541236, -2.778751],
    ['Bureaux à Arras', 50.290853, 2.777303],
    ['Bureaux à Grenoble', 45.184039, 5.722752],
    ['Sarthe', 48.003300, 0.206723],
    ['Gironde', 44.836597, -0.581157],
    ['Vaucluse', 43.876778, 5.397163],
    ['Paris', 48.856579, 2.351521]
  ];

  const infowindow = new google.maps.InfoWindow();
  let marker, i;

  for (i = 0; i < locationsFrance.length; i++) {
    marker = new google.maps.Marker({
      position: new google.maps.LatLng(locationsFrance[i][1], locationsFrance[i][2]),
      map: mapFrance
    });

    google.maps.event.addListener(marker, 'click', (function(marker, i) {
      return function() {
        infowindow.setContent(locationsFrance[i][0]);
        infowindow.open(mapFrance, marker);
      }
    })(marker, i));
  }

  // 标记该地图已初始化
  initializedMaps.france = mapFrance;
}

// 初始化国外地图的函数
function initMapEtranger() {
  const mapEtranger = new google.maps.Map(document.getElementById('mapEtranger'), {
    zoom: 6,
    center: centre_france
  });

  const locationsEtranger = [
    ['Bureaux à Plérin', 48.541236, -2.778751],
    ['Bureaux à Arras', 50.290853, 2.777303],
    ['Bureaux à Grenoble', 45.184039, 5.722752],
    ['Nouvelle-Zélande', -42.425169, 172.390052],
    ['Guyane', 4.648057, -52.817376],
    ['République Dominicaine', 18.895404, -70.224045]
  ];

  const infowindow = new google.maps.InfoWindow();
  let marker, i;

  for (i = 0; i < locationsEtranger.length; i++) {
    marker = new google.maps.Marker({
      position: new google.maps.LatLng(locationsEtranger[i][1], locationsEtranger[i][2]),
      map: mapEtranger
    });

    google.maps.event.addListener(marker, 'click', (function(marker, i) {
      return function() {
        infowindow.setContent(locationsEtranger[i][0]);
        infowindow.open(mapEtranger, marker);
      }
    })(marker, i));
  }

  // 标记该地图已初始化
  initializedMaps.etranger = mapEtranger;
}

function openMap(evt, mapName) {
  // 原有的标签切换逻辑保留
  var i, tabcontent, tablinks;
  tabcontent = document.getElementsByClassName("tabcontent_map");
  for (i = 0; i < tabcontent.length; i++) {
    tabcontent[i].style.display = "none";
  }
  tablinks = document.getElementsByClassName("tablinks_map");
  for (i = 0; i < tablinks.length; i++) {
    tablinks[i].className = tablinks[i].className.replace(" active", "");
  }
  document.getElementById(mapName).style.display = "block";
  evt.currentTarget.className += " active";

  // 新增:判断并初始化对应地图
  if (mapName === 'France' && !initializedMaps.france) {
    initMapFrance();
  } else if (mapName === 'Etranger' && !initializedMaps.etranger) {
    initMapEtranger();
  }
}

// 页面加载完成后,默认打开第一个标签并初始化对应地图
function init() {
  document.getElementById("defaultOpen").click();
}

为什么这样修改能解决问题?

当你切换到第二个标签页时,#mapEtranger容器已经被设置为display: block,此时再初始化地图,Google Maps API就能正确读取容器的宽高,渲染出正常的地图。同时我们用initializedMaps对象来记录已初始化的地图,避免重复初始化造成性能浪费。

另外,如果你不想拆分初始化函数,也可以在切换标签后,对已初始化但显示异常的地图触发resize事件:

google.maps.event.trigger(mapEtranger, 'resize');
mapEtranger.setCenter(centre_france); // 重新设置中心点,避免地图偏移

不过这种方式不如“按需初始化”来得稳妥,推荐用前面的方案哦!

内容的提问来源于stack exchange,提问作者Gurvan777

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:52:57