在您的网站上,找到处理click
您的标记之一上的事件的 JavaScript 代码。您将在map.html
页面本身中找到代码:
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 9,
center: new google.maps.LatLng(37.75538, -122.201983),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker, i, currentMarker = "null";
for (i = 0; i < locations.length; i++) {
marker = new MarkerWithLabel({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
draggable: false,
clickable: true,
map: map,
labelContent: locations[i][3],
labelAnchor: new google.maps.Point(22, 0),
labelClass: "maplabels", // the CSS class for the label
labelStyle: {opacity: 1.0}
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
// in case they open a new info window without closing the old one, stop animation
if (currentMarker != "null")
currentMarker.setAnimation(null);
marker.setAnimation(google.maps.Animation.BOUNCE);
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
currentMarker = marker;
}
})(marker, i));
google.maps.event.addListener(infowindow, 'closeclick', function() {
currentMarker.setAnimation(null);
});
}
现在处理点击的实际代码在中间:
if (currentMarker != "null")
currentMarker.setAnimation(null);
marker.setAnimation(google.maps.Animation.BOUNCE);
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
currentMarker = marker;
if
使用 Chrome 或您喜欢的浏览器中的 JavaScript 调试器,通过单击左边距在此代码(语句)的第一行设置断点。使用开发人员工具中的 Sources 选项卡打开代码。
如果你不熟悉 JavaScript 开发者工具,这里有JavaScript 调试介绍和Chrome DevTools 详细介绍。
现在您已经设置了断点,请单击其中一个标记。它应该停在您设置断点的代码行上。
现在使用调试器中的 Step Over 命令来单步执行该代码。在 Windows 上,您可以在此处使用 F10 键。当您尝试执行此行时,您会看到错误发生:
infowindow.open(map, marker);
那么这里有什么问题呢?在 Chrome 调试器中,您可以将鼠标悬停在源代码中的任何变量上以查看其当前值。
如果您查看marker
变量,它看起来似乎相当合理,其属性确实与地图和标记等有关。
但是看看map
变量。它看起来像这样:
Object {9: false, 16: false, 18: false, 27: false, 65: false}
这看起来不太像 Google Maps API 对象,是吗?事实上,其中一些数字听起来很熟悉。65
是字母的字符代码'a'
,27
是Escape
,9
是Tab
键。
看起来你的代码中的其他地方,一些其他代码已经用一个不相关的同名变量覆盖了你的全局变量。map
事实上,这个名字是有道理的:map
对象是某种从字符代码到布尔值的映射(在计算机科学意义上,而不是地理意义上)。
map
一个简单的解决方法是将变量的名称更改为gmap
与其他变量不冲突的其他名称map
。或者更好的是,您可以将所有这些映射代码包装在一个函数中,以便您的map
变量是该函数的本地变量,并且不会被其他地方的全局变量覆盖。
但也有可能另一个map
变量的存在本身就是一个错误!代码中的其他地方可能有一些函数意味着它map
是一个局部变量,但只是忘记var
在它上面使用 a ,所以它变成了全局变量。
虽然我有你,但你可以通过去掉事件处理程序中的函数返回函数来稍微简化标记创建代码。您这样做是为了获得标记变量的闭包,但这是一种不必要的复杂方法。相反,您可以简单地将整个for
循环体放在它自己的函数中。调用该函数将为您提供所需的闭包,而不会出现极其混乱的函数返回函数。
此外,您不需要使用字符串"null"
来指示不存在的currentMarker
值。
最后,您在 infowindow 上为每个 marker设置一个事件侦听器,即使您只有一个 infowindow。您可以设置此事件侦听器一次。
结合这些想法,您最终可能会得到:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 9,
center: new google.maps.LatLng(37.75538, -122.201983),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(
infowindow, 'closeclick', stopAnimation
);
var currentMarker;
for (i = 0; i < locations.length; i++) {
addMarker( locations[i] );
}
function addMarker( location ) {
var marker = new MarkerWithLabel({
position: new google.maps.LatLng(location[1], location[2]),
draggable: false,
clickable: true,
map: map,
labelContent: location[3],
labelAnchor: new google.maps.Point(22, 0),
labelClass: "maplabels", // the CSS class for the label
labelStyle: {opacity: 1.0}
});
google.maps.event.addListener(marker, 'click', function() {
stopAnimation();
marker.setAnimation(google.maps.Animation.BOUNCE);
infowindow.setContent(location[0]);
infowindow.open(map, marker);
currentMarker = marker;
});
}
function stopAnimation() {
currentMarker && currentMarker.setAnimation(null);
currentMarker = null;
}
}
initMap();