我尝试在InfoWindow中插入带有表单的标记,但是第一次点击进入地图时出现了这个错误:
Uncaught TypeError: Cannot set property 'value' of null
这是因为getElementById
是NULL
,当我第二次点击时它匹配。我尝试了几个小时但没有得到它: - /
我的代码(部分内容):
<!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>';
答案 0 :(得分:1)
它与您在infoWindow
正确打开之前尝试访问表单的隐藏元素有关。
编辑:这是一种方法,但它需要一些重新调整。
我正在使用String.replace
来更改表单的值。我不知道是否有更简单的方法使用vanilla 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');
}
如果您需要有关我使用的正则表达式的信息,请查看此answer。
答案 1 :(得分:1)
当您使用字符串作为InfoWindow的内容时,InfoWindow中的元素在打开InfoWindow之前不可用(domready
)
但是你不能使用字符串作为内容,youz也可以直接使用DOMNode,无论是否已将其注入文档,该节点始终都是可访问的。
所以解决方案:根据form
- 字符串创建一个DOMNode,并将其用作信息窗 - 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);
}
});
}
&#13;
html,body,#map-canvas{
padding:0;
margin:0;
height:100%;
}
&#13;
<div id="map-canvas"></div>
<script src="https://maps.googleapis.com/maps/api/js?v=3&callback=initJsMap" async defer></script>
&#13;