Google Maps InfoWindow内容重复求助:所有窗口显示最后数组对象内容
解决Google Maps所有InfoWindow显示相同内容的问题
兄弟,这个问题我之前踩过无数次坑!这是典型的闭包作用域陷阱导致的,咱们一步步来捋清楚:
问题根源
你循环里的i没有用块级作用域声明(既没加let/const,甚至连var都没写,变成了全局变量),所有的点击事件回调函数都共享同一个i的引用。当循环跑完后,i的值已经变成了data.length,这时候触发点击事件,回调里访问的data[i]其实指向的是数组最后一个元素,自然所有InfoWindow都显示最后一条内容。
两种快速解决方案
方案1:用let声明循环变量(最简洁)
ES6的let提供了块级作用域,每次循环迭代都会创建一个独立的i变量,完美解决共享引用的问题:
function addMapMarkers(data) { removeMarkers(); // 把i用let声明,每个循环迭代的i都是独立的 for(let i=0; i<data.length; i++){ var location = {lat: + data[i].koordinatLatLng[0], lng: + data[i].koordinatLatLng[1]}; var marker = new google.maps.Marker({ position: location, map: map, clickable: true }); marker.info = new google.maps.InfoWindow({ content: "Navn: " + data[i].navn }); google.maps.event.addListener(marker, 'click', function() { marker.info.open(map, marker); }); // 记得把marker存入数组,方便removeMarkers()移除 markers.push(marker); } }
方案2:用立即执行函数(IIFE)创建闭包(兼容旧环境)
如果你的项目需要兼容不支持ES6的环境,可以用立即执行函数把当前循环的索引/数据包裹起来,保存独立的引用:
function addMapMarkers(data) { removeMarkers(); for(var i=0; i<data.length; i++){ // 用IIFE创建闭包,把当前的i作为index传进去 (function(index) { var location = {lat: + data[index].koordinatLatLng[0], lng: + data[index].koordinatLatLng[1]}; var marker = new google.maps.Marker({ position: location, map: map, clickable: true }); marker.info = new google.maps.InfoWindow({ content: "Navn: " + data[index].navn }); google.maps.event.addListener(marker, 'click', function() { marker.info.open(map, marker); }); markers.push(marker); })(i); } }
额外提醒
别忘了把创建的marker对象存入一个数组(比如我代码里的markers),这样removeMarkers()函数才能正确找到并移除这些标记,不然之前的移除操作可能会失效哦。
内容的提问来源于stack exchange,提问作者Vertex
相关产品推荐
相关产品推荐

