繁体   English   中英

Google Maps API使用表单添加标记,但是只有在第二次单击后才能使用getElementById

[英]Google Maps API add marker with form, but getElementById only after second click

我尝试在InfoWindow中插入带有表单的标记,但是第一次单击地图时出现此错误:

Uncaught TypeError: Cannot set property 'value' of null

这是因为getElementByIdNULL ,当我再次单击它匹配时。 我尝试了几个小时,但没有得到:-/

我的代码(的一部分):

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">

<script src="https://maps.googleapis.com/maps/api/js"></script>
<script>

var map;
var marker;

function initJsMap() {
  var vienna = new google.maps.LatLng(48.2134567, 16.3789012);
  var mapOptions = {
    position: vienna,
    zoom: 12,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };

  map = new google.maps.Map(document.getElementById("map-canvas"),mapOptions);

  google.maps.event.addListener(map, 'dblclick', function(event) {
    placeMarker(event.latLng);
  });

}

function placeMarker(location) {
  if (marker) {
    marker.setPosition(location);
  } else {
    var form = '<div id="form_canvasform">' +
                '<form method="POST" action="/addmap" name="form_canvas">' +
                '<div style="display:none;">' +
                '<input id="csrf_token" name="csrf_token" type="hidden" value="foo">' +
                '<input id="latitude" name="latitude" type="hidden" value="">' +
                '<input id="longitude" name="longitude" type="hidden" value=""></div>' +
                '<label for="link">link</label> <input id="link" name="link" type="text" value="">' +
                '<input type="submit" value="Go!">' +
                '</form>' +
                '</div>';
    infowindow = new google.maps.InfoWindow({
      content: form
    });
    marker = new google.maps.Marker({
      position: location,
      map: map,
      draggable: true
    });
    infowindow.open(map, marker);
    marker.addListener('click', function() {
      infowindow.open(map, marker);
    });
  }
  console.log("Latitude: " + location.lat());
  console.log("Longitude: " + location.lng());
  console.log(form);
  document.getElementById('latitude').value = location.lat();
  document.getElementById('longitude').value = location.lng();
}

</script>
</head>
<body onload="initJsMap()">
<div id="map-canvas" style="width:50%; height:600px;"></div>
</body>
</html>

表单内容由jinja2模板引擎(带烧瓶)生成。 使用console.log()可以获得正确的值。

[编辑]:

这是生成表单的jinja代码:

    var form = '<div id="form_canvasform">' +
      '<form method="POST" action="{{ request.path }}" name="form_canvas">' +
      '{{ form.hidden_tag() }}' +
      '{{ form.link.label }} {{ form.link }}' +
      '<br/>' +
      '<input type="submit" value="Go!">' +
      '</form>' +
      '</div>';

它与您尝试正确打开infoWindow之前尝试访问表单的隐藏元素有关。

编辑:这是一种方法,但是需要重新安排。

我正在使用String.replace更改表单的值。 我不知道是否有使用香草JavaScript进行操作的更简便方法(因为使用jQuery进行操作更容易),但它似乎可以工作。

var map;
var marker;

// regex to look for in HTML string
var latRe = /(<input id="latitude" name="latitude" type="hidden" value=")(.*)("><input id="longitude")/; 
var lngRe = /(<input id="longitude" name="longitude" type="hidden" value=\")(.*)(">.*<label)/;

function initJsMap () {
  var vienna = new google.maps.LatLng(48.2134567, 16.3789012);
  var mapOptions = {
    center: vienna, // 'center', not 'position'
    zoom: 12,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };

  map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
  marker = new google.maps.Marker({  map: map, draggable: true });
  infowindow = new google.maps.InfoWindow();

  google.maps.event.addListener(map, 'dblclick', function(event) {
      placeMarker(event.latLng);
  });

  marker.addListener('click', function() {
      infowindow.open(map, marker);
  });
}

function placeMarker (location) {
    var form = 
      '<div id="form_canvasform">' +
      '<form method="POST" action="/addmap" name="form_canvas">' +
      '<div style="display:none;">' +
      '<input id="csrf_token" name="csrf_token" type="hidden" value="foo">' +
      '<input id="latitude" name="latitude" type="hidden" value="">' +
      '<input id="longitude" name="longitude" type="hidden" value=""></div>' +
      '<label for="link">link</label> <input id="link" name="link" type="text" value="">' +
      '<input type="submit" value="Go!">' +
      '</form>' +
      '</div>';
    // ugly: replace the values in the HTML string with the new values using regex
    form = form.replace(latRe, '$1' + location.lat() + '$3');
    form = form.replace(lngRe, '$1' + location.lng() + '$3');
    // set the new form
    infowindow.setContent(form);
    // set the new position of the marker
    marker.setPosition(location);
    // open infowindow
    google.maps.event.trigger(marker, 'click');
}

如果您需要有关我使用的正则表达式的信息,请检查此答案

演示

当您使用字符串作为InfoWindow的内容时,InfoWindow中的元素在打开InfoWindow之前是不可用的(是domready

但是您一定不能使用字符串作为内容,您也可以直接使用DOMNode,无论是否已将其插入文档中,该节点始终可以访问。

因此,解决方案是:基于-string form创建一个DOMNode,并将其用作infowindow- content

演示:(我修改form了示范一点点,但它也将与原始字符串工作)

 function initJsMap() { var vienna = new google.maps.LatLng(48.2134567, 16.3789012), mapOptions = { center: vienna, zoom: 12, disableDoubleClickZoom:true }, map = new google.maps.Map(document.getElementById("map-canvas"),mapOptions), marker = new google.maps.Marker({draggable: true}), infowindow = new google.maps.InfoWindow({disableAutoPan:true}), form = '<div id="form_canvasform">' + '<form method="POST" action="/addmap" name="form_canvas">' + '<input id="latitude" name="latitude" value=""><br/>' + '<input id="longitude" name="longitude" value="">' + '</form>' + '</div>'; node = document.createElement('div'), content; node.innerHTML = form; content = node.firstChild infowindow.setContent(content); google.maps.event.addListener(map, 'dblclick', function(event) { marker.setOptions({position:event.latLng,map:map}); infowindow.open(map,marker); }); google.maps.event.addListener(marker, 'click', function(event) { marker.setPosition(event.latLng); infowindow.open(map,marker); }); google.maps.event.addListener(marker, 'position_changed', function() { content.querySelector('input[name="latitude"]').value = this.getPosition().lat(); content.querySelector('input[name="longitude"]').value = this.getPosition().lng(); if(infowindow.getMap()){ infowindow.open(map,marker); } }); } 
 html,body,#map-canvas{ padding:0; margin:0; height:100%; } 
 <div id="map-canvas"></div> <script src="https://maps.googleapis.com/maps/api/js?v=3&callback=initJsMap" async defer></script> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM