You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Maps标记数组addListener点击事件异常问题求助

问题解决:Google Maps标记点击事件始终触发最后一个标记的事件

问题核心原因

这是循环中闭包作用域导致的经典问题:你在循环里定义的点击事件函数,捕获的是变量i的引用而非每次循环时i的具体值。当循环完全结束后,i已经变成了info.length,所以所有标记的点击事件触发时,都会调用这个最终值。

三种可行解决方案

1. 使用ES6 let关键字(最简方案)

把循环变量i改成let声明,let会在每次循环迭代时创建独立的变量绑定,确保每个事件函数捕获当前循环的i值:

for (let i = 0; i < info.length; i++) {
    toilet = info[i];
    map_number = toilet.map_number;

    if (typeof marker_list[map_number][toilet.id] === "undefined") {
        unique_id = map_number + "_" + toilet.id;
        toilet_lat = parseFloat(toilet.lat);
        toilet_lng = parseFloat(toilet.lng);
        marker_x = parseFloat(toilet.marker_anchor_x);
        marker_y = parseFloat(toilet.marker_anchor_y);
        label_x = parseFloat(toilet.label_anchor_x);
        label_y = parseFloat(toilet.label_anchor_y);
        marker_anchor = new google.maps.Point(marker_x, marker_y);
        label_anchor = new google.maps.Point(label_x, label_y);

        marker[i] = new google.maps.Marker({
            position: {
                lat: toilet_lat,
                lng: toilet_lng
            },
            map: map,
            icon: {
                path: toilet.marker_path,
                anchor: marker_anchor,
                labelOrigin: label_anchor,
                fillColor: toilet.marker_colour,
                fillOpacity: 1,
                strokeWeight: 2,
                strokeColor: 'black'
            },
            opacity: toilet.marker_opacity,
            draggable: toilet.marker_draggable
        });

        marker[i].addListener('click', function() {
            alert(i);
        });
    }

    marker_list[map_number][toilet.id] = marker[i];
}

2. 立即执行函数(IIFE)兼容ES5环境

如果需要兼容旧浏览器,用立即执行函数把当前i值封装到独立作用域:

for (i = 0; i < info.length; i++) {
    toilet = info[i];
    map_number = toilet.map_number;

    if (typeof marker_list[map_number][toilet.id] === "undefined") {
        // 省略标记创建代码...

        marker[i] = new google.maps.Marker({/* 配置参数 */});

        // 用IIFE捕获当前循环的i值
        (function(currentIndex) {
            marker[currentIndex].addListener('click', function() {
                alert(currentIndex);
            });
        })(i);
    }

    marker_list[map_number][toilet.id] = marker[i];
}

3. 给标记绑定自定义属性

直接把索引值存到Marker对象上,点击时通过this访问:

for (i = 0; i < info.length; i++) {
    toilet = info[i];
    map_number = toilet.map_number;

    if (typeof marker_list[map_number][toilet.id] === "undefined") {
        // 省略标记创建代码...

        marker[i] = new google.maps.Marker({/* 配置参数 */});
        marker[i].index = i; // 添加自定义属性存储当前索引

        marker[i].addListener('click', function() {
            alert(this.index);
        });
    }

    marker_list[map_number][toilet.id] = marker[i];
}

额外优化提示

  • 原代码中marker_list[map_number][toilet.id] = new Array();后又赋值为marker是冗余操作,直接赋值单个标记marker[i]更合理。
  • 变量toilet、map_number等建议用let/var声明,避免全局变量污染。

内容的提问来源于stack exchange,提问作者Felicity Penfold

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 02:15:35