【问题标题】:google map Cannot read property 'open' of undefined谷歌地图无法读取未定义的属性“打开”
【发布时间】:2017-11-09 13:40:30
【问题描述】:

$(document).on("click", "#searchRankingLocation", function() {
    map = new google.maps.Map(document.getElementById('map'), {
        center: {
            lat: 37.402040,
            lng: 127.107296
        }, //usepace
        zoom: 7
    });
    for (var i = 0; i < locationList.length; i++) {
        markers[i] = new google.maps.Marker({
            map: map,
            draggable: true,
            animation: google.maps.Animation.DROP,
            position: locationList[i],
            title: rankingInfoList[i].name
        });
        infoList[i] = 'this area will changed.'

        windowNames[i] = new google.maps.InfoWindow({
            content: infoList[i]
        });
        google.maps.event.addListener(markers[i], 'click', function() {
            windowNames[i].open(map, markers[i]);
        });

    }
});
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"&gt;&lt;/script&gt;

这是我的来源。
我无法向您显示窗口,我试图找到很多解决方案但他们没有帮助我!

【问题讨论】:

  • windowNames、markers、infoList 只是数组。
  • 是的,一旦代码格式正确,阅读起来就会容易得多
  • 问题是点击事件发生后i 的值......它将是locationList.length - 这显然是错误的
  • 对不起。这是我在 stackoverflow 中的第一个问题。
  • umm... locationList 是我数据库中 ajax 的数组。

标签: javascript google-maps


【解决方案1】:

在您的原始代码中,var i 实质上使 i 变量作用域在循环之外,因此当点击事件发生时,我将是 locationList.length - 所以,显然 windowNames[i] 将是未定义的

p>

克服这个问题的三种方法

使用函数(我在这段代码中称之为doInfo

$(document).on("click", "#searchRankingLocation", function() {
    map = new google.maps.Map(document.getElementById('map'), {
        center: {
            lat: 37.402040,
            lng: 127.107296
        }, //usepace
        zoom: 7
    });
    function doInfo(marker, windowName) {
        google.maps.event.addListener(marker, 'click', function() {
            windowName.open(map, marker);
        });
    }
    for (var i = 0; i < locationList.length; i++) {
        markers[i] = new google.maps.Marker({
            map: map,
            draggable: true,
            animation: google.maps.Animation.DROP,
            position: locationList[i],
            title: rankingInfoList[i].name
        });
        infoList[i] = 'this area will changed.'

        windowNames[i] = new google.maps.InfoWindow({
            content: infoList[i]
        });
        doInfo(markers[i], windowNames[i]);
    }
});

在这种情况下,函数接收当前标记/窗口名称,因此i 的值现在无关

使用 IIFE(立即调用函数表达式)

$(document).on("click", "#searchRankingLocation", function() {
    map = new google.maps.Map(document.getElementById('map'), {
        center: {
            lat: 37.402040,
            lng: 127.107296
        }, //usepace
        zoom: 7
    });
    for (var i = 0; i < locationList.length; i++) {
        markers[i] = new google.maps.Marker({
            map: map,
            draggable: true,
            animation: google.maps.Animation.DROP,
            position: locationList[i],
            title: rankingInfoList[i].name
        });
        infoList[i] = 'this area will changed.'

        windowNames[i] = new google.maps.InfoWindow({
            content: infoList[i]
        });
        (function(x) { // the IIFE
            google.maps.event.addListener(markers[x], 'click', function() {
                windowNames[x].open(map, markers[x]);
            });

        })(i); //pass in the current value of i, used as x in the body of the IIFE
    }
});

这与第一种情况非常相似,只是该函数是“内联”的,因此某些人可能认为它更具可读性 - x 是每次迭代的 i 的“捕获”值 - 或者你也可以做

        (function(marker, windowName) { // the IIFE
            google.maps.event.addListener(marker, 'click', function() {
                windowName.open(map, marker);
            });

        })(markers[i], windowNames[i]);

所以,您可以看到这与第一个答案几乎相同

使用 ES2015 let - 这只能在 现代 浏览器中工作(无需转译)(所以,忘记 Internet Explorer)

$(document).on("click", "#searchRankingLocation", function() {
    map = new google.maps.Map(document.getElementById('map'), {
        center: {
            lat: 37.402040,
            lng: 127.107296
        }, //usepace
        zoom: 7
    });
    for (let i = 0; i < locationList.length; i++) {
        markers[i] = new google.maps.Marker({
            map: map,
            draggable: true,
            animation: google.maps.Animation.DROP,
            position: locationList[i],
            title: rankingInfoList[i].name
        });
        infoList[i] = 'this area will changed.'

        windowNames[i] = new google.maps.InfoWindow({
            content: infoList[i]
        });
        google.maps.event.addListener(markers[i], 'click', function() {
            windowNames[i].open(map, markers[i]);
        });
    }
});

let i 表示循环的每次迭代,i 的值被“捕获”用于该迭代

同样,这也可以这样做:

        // ...
        let marker = markers[i];
        let windowName = windowNames[i];

        google.maps.event.addListener(marker, 'click', function() {
            windowName.open(map, marker);
        });
        // ...

所以,归根结底,您可以看到所有方法的最终结果都是相同的

【讨论】:

  • 我认为你是个天才。非常感谢你。
  • 困扰了两天。但是您在短时间内解决了问题..谢谢..太棒了..
猜你喜欢
  • 2017-04-03
  • 1970-01-01
  • 2021-11-03
  • 2018-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多