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

Google地图InfoWindow仅单条路线生效问题求助及功能优化需求

我来帮你搞定这几个Google Maps的问题,咱们一步步拆解解决:

先说说你遇到的问题根源

  1. 仅1条路线显示InfoWindow:你在循环路线段(legs)时,一直复用同一个infowindow实例,每次都会覆盖之前的内容和位置,最后只会保留最后一条路线的信息。
  2. 关闭InfoWindow后无法再次打开:一是你没给路线或任何元素绑定重新打开的触发事件;二是全局的infowindow变量被局部变量覆盖了,导致后续无法正确引用实例。
  3. 路线中点点击触发InfoWindow:可以通过给每个路线段中点创建透明标记(Marker)绑定点击事件,或者直接监听路线的点击事件来实现。

修改后的完整代码

JavaScript部分

var geocoder;
var map;
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var locations = [
  ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
  ['Bondi Beach', -33.890542, 151.274856, 4],
  ['Coogee Beach', -33.923036, 151.259052, 5],
  ['Maroubra Beach', -33.950198, 151.259302, 1],
  ['Cronulla Beach', -34.028249, 151.157507, 3]
];
var infowindow; // 全局变量,避免被局部覆盖
var legMarkers = []; // 存储每个路线段中点的透明标记

function initialize() {
  directionsDisplay = new google.maps.DirectionsRenderer();
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: 10,
    center: new google.maps.LatLng(-33.92, 151.25),
    mapTypeId: google.maps.MapTypeId.ROADMAP
  });
  directionsDisplay.setMap(map);
  infowindow = new google.maps.InfoWindow(); // 直接赋值给全局变量,去掉var

  var marker, i;
  var request = {
    travelMode: google.maps.TravelMode.DRIVING
  };

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

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

    if (i == 0) request.origin = marker.getPosition();
    else if (i == locations.length - 1) request.destination = marker.getPosition();
    else {
      if (!request.waypoints) request.waypoints = [];
      request.waypoints.push({
        location: marker.getPosition(),
        stopover: true
      });
    }
  }

  directionsService.route(request, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      directionsDisplay.setDirections(response);
      var route = response.routes[0];
      var summaryPanel = document.getElementById("directions_panel");
      summaryPanel.innerHTML = "";

      // 清空之前的路线段标记
      legMarkers.forEach(marker => marker.setMap(null));
      legMarkers = [];

      // 遍历每个路线段,创建中点标记并绑定InfoWindow
      for (var i = 0; i < route.legs.length; i++) {
        var routeSegment = i + 1;
        summaryPanel.innerHTML += "<b>Route Segment: " + routeSegment + "</b><br />";
        summaryPanel.innerHTML += route.legs[i].start_address + " to ";
        summaryPanel.innerHTML += route.legs[i].end_address + "<br />";
        summaryPanel.innerHTML += route.legs[i].distance.text + "<br /><br />";

        // 获取当前路线段的中点位置(用路线段自身的路径计算,更精准)
        var legPath = route.legs[i].steps.map(step => step.path).flat();
        var centerIndex = Math.floor(legPath.length / 2);
        var center = legPath[centerIndex];

        // 创建透明标记(用户看不到,但能触发点击)
        var legMarker = new google.maps.Marker({
          position: center,
          map: map,
          opacity: 0,
          title: `Route Segment ${routeSegment}`
        });
        legMarkers.push(legMarker);

        // 给透明标记绑定点击事件,打开对应路线段的InfoWindow
        google.maps.event.addListener(legMarker, 'click', (function(leg, centerPos) {
          return function() {
            infowindow.setPosition(centerPos);
            infowindow.setContent(`${leg.duration.text}<br>${leg.distance.text}`);
            infowindow.open(map);
          }
        })(route.legs[i], center));
      }

      // 可选:监听路线任意位置的点击,显示点击位置的基础信息
      google.maps.event.addListener(directionsDisplay, 'click', function(event) {
        infowindow.setPosition(event.latLng);
        infowindow.setContent(`点击位置:${event.latLng.lat().toFixed(6)}, ${event.latLng.lng().toFixed(6)}`);
        infowindow.open(map);
      });

      computeTotalDistance(response);
    } else {
      alert("directions response " + status);
    }
  });
}

function computeTotalDistance(result) {
  var totalDist = 0;
  var totalTime = 0;
  var myroute = result.routes[0];
  for (i = 0; i < myroute.legs.length; i++) {
    totalDist += myroute.legs[i].distance.value;
    totalTime += myroute.legs[i].duration.value;
  }
  totalDist = totalDist / 1000;
  document.getElementById("total").innerHTML = "total distance is: " + totalDist + " km<br>total time is: " + (totalTime / 60).toFixed(2) + " minutes";
}

google.maps.event.addDomListener(window, "load", initialize);

HTML部分

<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
  <title>Google Maps Multiple Markers</title>
  <script src="http://maps.google.com/maps/api/js?key=AIzaSyDYeDBDl-8Wx98Az55EbVnpvRfSIBbwxyE&libraries=places"></script>
</head>
<div id="map" style="float:left;width: 500px; height: 400px;"></div>
<div id="control_panel" style="float:right;width:30%;text-align:left;padding-top:20px">
  <div id="directions_panel" style="margin:20px;background-color:#FFEE77;"></div>
  <div id="total"></div>
</div>

关键修改说明

  1. 修复变量作用域:去掉initialize里的var infowindow,确保全局变量能正确引用InfoWindow实例,关闭后可以重新打开。
  2. 多路线InfoWindow支持:为每个路线段的中点创建透明Marker,每个Marker绑定独立的点击事件和对应内容,解决了单条路线显示的问题。
  3. 点击触发功能:通过透明Marker实现路线中点点击打开InfoWindow,还额外添加了路线任意位置点击的监听(可选),满足你点击路线触发的需求。
  4. 精准中点计算:不再用全局路线的中点,而是用每个路线段自身的路径计算中点,对应更准确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:30:45