航点输入字段不能用作搜索框,或者 return 结果偏向地图边界

Waypoint input fields do not work as SearchBoxes, or return results biased towards the map bounds

我正在制作自行车路线规划器,用户可以在其中通过单击按钮为 waypoints 创建新的输入字段。

我希望每次单击 'Add waypoint' 按钮都创建一个新的航路点输入字段(最多 8 个),并且对于这些创建的每个输入字段都是 SearchBox,返回结果有偏差朝向地图的边界,并在单击 'Show route' 按钮时包含为 waypoints。

目前,代码将为 waypoints 创建新的输入字段,这些字段在创建路线时包含在内,但这些新创建的输入字段无法用作搜索框,结果偏向于地图边界。

Github 托管版本:https://gregkaighin.github.io/bicycle-route-planner/ (此问题中提供的最小版本)

Github 托管版本:https://8000-silver-carp-d746l0fo.ws-eu03.gitpod.io/routes.html(项目的完整版本)

    const bedfordshire = {
    lat: 52.02973,
    lng: -0.45303
};

const mapOtions = {
    center: bedfordshire,
    zoom: 10,
};

const map = new google.maps.Map(document.getElementById('map'), mapOtions);
const directionsService = new google.maps.DirectionsService();
const directionsDisplay = new google.maps.DirectionsRenderer({
});
const waypoints = document.getElementsByName("waypoints[]");
for (var i = 0; i < waypoints.length; i++);

function calcRoute() {
    var waypts = [];
    var waypointElmts = document.getElementsByName('waypoints[]');
    for (var i = 0; i < waypointElmts.length; i++) {
        if (waypointElmts[i].value.length > 0) {
            waypts.push({
                location: waypointElmts[i].value,
            });
        }
    }
    var request = {
        origin: document.getElementById('from').value,
        destination: document.getElementById('to').value,
        travelMode: google.maps.TravelMode.BICYCLING,
        unitSystem: google.maps.UnitSystem.IMPERIAL,
        waypoints: waypts,
        optimizeWaypoints: false,
    }
    directionsService.route(request, function (response, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            directionsDisplay.setDirections(response);
            directionsDisplay.setMap(map);           
        }  
    });
}

// Create searchBox objects for from and to
var input1 = document.getElementById('from');
var searchBox1 = new google.maps.places.SearchBox(input1);
map.addListener('bounds_changed', () => {
    searchBox1.setBounds(map.getBounds());
});

var input2 = document.getElementById('to');
var searchBox2 = new google.maps.places.SearchBox(input2);
map.addListener('bounds_changed', () => {
    searchBox2.setBounds(map.getBounds());
});

// Functions to create and delete new waypoint search boxes
$(document).ready(function () {
    // Set the maximum number of waypoint inputs
    var max_fields = 9;
    var wrapper = $(".waypoint-input-fields");
    var add_button = $(".add_form_field");

    var x = 1;
    $(add_button).click(function (e) {
        e.preventDefault();
        if (x < max_fields) {
            x++;
            //Add a new input box
            $(wrapper).append('<div><input type="text" id="waypoint-inputs" class="form-control" 
name="waypoints[]"/><a href="#" class="delete"> <i class="fas fa-times"></i></a></div>');
        } else {
            alert('Maximum number of waypoints allowed is 8')
        }
    });
    // Delete input box
    $(wrapper).on("click", ".delete", function (e) {
        e.preventDefault();
        $(this).parent('div').remove();
        x--;
    })
});

    <!DOCTYPE html>
<html lang="en-us">

<head>
    <meta name="viewport" content="initial-scale=1.0">
    <meta charset="utf-8">
    <title>Bicycle Route Planner</title>
    <link rel="stylesheet" type="text/css" href="assets/css/style.css">
</head>

<body>
    <label for="from" class="control-label direction-input"></label>
    <input type="text" id="from" placeholder="Start" class="form-control">
    <!-- Button to add new field for waypoints -->
    <div class="waypoint-input-fields">
        <button class="add_form_field">Add a waypoint</button>
        <label for="to" class=" control-label direction-input form-inline"></label>
        <input type="text" id="to" placeholder="End" class="form-control">
        <button onclick="calcRoute();">Show Route</button>
    </div>
    <div id="map">
    </div>
    <div id="route-summary">
    </div>
    <div id="directions-panel">
    </div>
    <!-- Google maps API -->
    <script
        src="https://maps.googleapis.com/maps/api/js? 
key=AIzaSyCZA8vB1HcWG1pqWyUyBcyuRI2VDi_fU9U&callback&libraries=places">
    </script>
    <!-- jQuery -->
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js">
    </script>
    <!-- Routes -->
    <script src="assets/js/map.js"></script>

</body>

</html>

    #map {
    width: 85vw;
    height: 48vh;
    margin: auto;
    
}

#directions-panel {
  margin: auto;
  min-width: fit-content;
}

考虑以下因素。

$(function() {
  const bedfordshire = {
    lat: 52.02973,
    lng: -0.45303
  };

  const mapOtions = {
    center: bedfordshire,
    zoom: 10,
  };

  const map = new google.maps.Map(document.getElementById('map'), mapOtions);
  const directionsService = new google.maps.DirectionsService();
  const directionsDisplay = new google.maps.DirectionsRenderer({});

  function calcRoute() {
    var waypts = [];
    $(".waypoint").each(function(i, el) {
      if ($(el).val().length > 0) {
        waypts.push({
          location: $(el).val(),
        });
      }
    });
    var request = {
      origin: $('#from').val(),
      destination: $('#to').val(),
      travelMode: google.maps.TravelMode.BICYCLING,
      unitSystem: google.maps.UnitSystem.IMPERIAL,
      waypoints: waypts,
      optimizeWaypoints: false,
    };
    directionsService.route(request, function(response, status) {
      if (status == google.maps.DirectionsStatus.OK) {
        directionsDisplay.setDirections(response);
        directionsDisplay.setMap(map);
      }
    });
  }

  function createSearchBox(field, target) {
    if (field == undefined) {
      var holder = $("<div>").appendTo(target);
      field = $("<input>", {
        type: "text",
        class: "form-control search-box waypoint",
        id: "waypoint-" + ($(".waypoint").length + 1),
        placeholder: "Waypoint"
      });
      holder.append(field);
      holder.append("<a href='#' class='delete'> <i class='fas fa-times'></i></a>");
    } else {
      field = $(field);
    }
    var searchbox = new google.maps.places.SearchBox(field.get(0));
    map.addListener("bounds_change", function() {
      searchbox.setBounds(maps.getBounds());
    });
  }

  createSearchBox("#from");
  createSearchBox("#to");

  // Set the maximum number of waypoint inputs
  var max_fields = 8;
  var wrapper = $(".waypoint-input-fields");
  var add_button = $(".add_form_field");

  add_button.click(function(e) {
    e.preventDefault();
    if ($(".waypoint").length < max_fields) {
      createSearchBox(undefined, wrapper);
    } else {
      alert('Maximum number of waypoints allowed is 8')
    }
  });

  // Delete input box
  $(wrapper).on("click", ".delete", function(e) {
    e.preventDefault();
    $(this).parent('div').remove();
  });
  
  $("#show-route").click(calcRoute);
});
#map {
  width: 85vw;
  height: 48vh;
  margin: auto;
}

#directions-panel {
  margin: auto;
  min-width: fit-content;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.3/css/fontawesome.min.css" integrity="sha384-wESLQ85D6gbsF459vf1CiZ2+rr+CsxRY0RpiF1tLlQpDnAgg6rwdsUF1+Ics2bni" crossorigin="anonymous">
<script src="https://maps.googleapis.com/maps/api/js? 
key=AIzaSyCZA8vB1HcWG1pqWyUyBcyuRI2VDi_fU9U&callback&libraries=places">
</script>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js">
</script>

<div class="start-input-fields">
  <label for="from" class="control-label direction-input"></label>
  <input type="text" id="from" placeholder="Start" class="form-control search-box">
  <button class="add_form_field">Add a waypoint</button>
</div>
<div class="waypoint-input-fields"></div>
<div class="end-input-fields">
  <label for="to" class="control-label direction-input form-inline"></label>
  <input type="text" id="to" placeholder="End" class="form-control search-box">
</div>
<button id="show-route">Show Route</button>
</div>
<div id="map"></div>
<div id="route-summary"></div>
<div id="directions-panel"></div>

在这里您可以看到如何为每个字段分配或添加 Google 搜索框。可以看到如果该字段存在,直接赋值即可。如果它确实发出鼻涕,您可以将其添加到特定目标。这是动态添加的,并使用 length 属性来确定添加了多少字段。