javascript - 谷歌地图弹出错误

标签 javascript google-maps google-maps-api-3

我的自定义谷歌地图代码突然停止工作,我不明白为什么。如果我将完全相同的代码粘贴到 jsfiddle 它工作正常,但是在 my site 它抛出一个错误:

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

Uncaught TypeError: Cannot call method 'unbindAll' of null

图钉出现在 map 上的正确位置,并通过上下弹跳适本地(一次)响应点击,但是弹出窗口不会弹出。给了什么?

最佳答案

在您的网站上,找到处理其中一个标记上的 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;

通过单击左边距,使用 Chrome 中的 JavaScript 调试器或您最喜欢的浏览器在此代码的第一行(if 语句)设置断点。使用开发人员工具中的源选项卡打开代码。

如果您不熟悉 JavaScript 开发人员工具,这里有一个 introduction to JavaScript debugging和一个 detailed introduction to the Chrome DevTools .

现在您已经设置了断点,单击您的标记之一。它应该在您设置断点的代码行处停止。

现在使用调试器中的 Step Over 命令逐步执行该代码。在 Windows 上,您可以在此处使用 F10 键。当您尝试执行此行时,您会看到错误发生:

            infowindow.open(map, marker);

那么这里有什么问题呢?在 Chrome 调试器中,您可以将鼠标悬停在源代码中的任何变量上以查看其当前值。

如果您查看 marker 变量,它看起来很合理,具有确实与 map 和标记等相关的属性。

但看看 map 变量。它看起来像这样:

Object {9: false, 16: false, 18: false, 27: false, 65: false}

这看起来不太像 Google Maps API 对象,是吗?事实上,其中一些数字听起来非常熟悉。 65是字母'a'的字符编码,27Escape9Tab 键。

它看起来像您代码中的其他地方,一些其他代码已经覆盖您的全局 map 变量,使用一个不相关的同名变量。事实上,这个名字有些道理:map 对象是某种从字符代码到 bool 值的映射(在计算机科学意义上,而不是在地理意义上)。

一个简单的修复方法是将您的 map 变量的名称更改为 gmap 或与其他 map< 不冲突的其他名称变量。或者更好的是,您可以将所有这些 map 代码包装在一个函数中,这样您的 map 变量就是该函数的局部变量,不会被其他地方的全局变量覆盖。

但也有可能另一个 map 变量的存在本身就是一个错误!代码中其他地方可能有一些函数意味着map 成为局部变量,但只是忘记在其上使用 var所以它变得全局化了。

虽然我知道了,但您可以通过删除事件处理程序中的返回函数的函数来稍微简化标记创建代码。您这样做是为了获得标记变量的闭包,但这是一种不必要的复杂方法。相反,您可以简单地将整个 for 循环放在它自己的函数中。调用该函数将为您提供所需的闭包,而无需极其困惑的函数返回函数。

此外,您不需要使用字符串 "null" 来指示不存在的 currentMarker 值。

最后,您要在信息窗口上为每个标记设置事件监听器,即使您只有一个信息窗口。您可以设置此事件监听器一次。

结合这些想法,您最终可能会得到:

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();

关于javascript - 谷歌地图弹出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18838419/

相关文章:

java - SupportMapFragment 在主线程上加载并卡住界面(忽略getMapAsync)

ios - Ionic ios 模拟器不加载谷歌地图

javascript - 可以在自定义街景 View 中禁用 ScrollWheel 吗?

android - 如何创建一个包含纬度和经度的数组并使用 for 循环在 android 中标记谷歌地图上的位置

javascript - 如何将变量从 Jade 传递到 .JS 文件?

javascript - MYSQL 表中未定义的结果

javascript - 如何将 Javascript 输出存储到表单中

javascript - 为中国用户动态切换 Google Maps API URL

javascript - JSON.parse 在带有数组的 for 循环内给出 SyntaxError

javascript - Material UI 3.9.3 未在 IE 中设置复选框样式