[英]InfoBox (getElementById) for each marker – Google Maps API 3
[英]Google Maps API add marker with form, but getElementById only after second click
我尝试在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>';
它与您尝试正确打开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.