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
相关产品推荐
相关产品推荐

