1

My custom google maps code stopped working all of a sudden and I can't figure out why. If I paste the same exact code into a jsfiddle it works fine, however on my site it throws an error:

Uncaught TypeError: Object #<Object> has no method 'O'

or

Uncaught TypeError: Cannot call method 'unbindAll' of null

The pins are appearing on the map in the correct locations and respond to clicks appropriately (once) by bouncing up and down, however the popups do not pop up. What gives?

4

1 回答 1

4

在您的网站上,找到处理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'27Escape9Tab键。

看起来你的代码中的其他地方,一些其他代码已经用一个不相关的同名变量覆盖了你的全局变量。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();
于 2013-09-16T23:19:53.507 回答