循环输出BMap.Marker标记

来源:互联网 发布:淘宝88会员 8.8折 编辑:程序博客网 时间:2024/05/18 00:56

要在地图上循环输出标记并给标记添加click事件,如果使用如下代码则所有标记被点击后infowindow输出的信息是一样的都是:考勤日期10,i 的值一直会是10

先看错误代码:

result = [...];//比如有10个数据for(var i=0;i<result.length;i++){var marker = new BMap.Marker(new BMap.Point(result[i].coordx, result[i].coordy)); var date = result[i].date;marker.addEventListener("click", function(e){var infoWindow = new BMap.InfoWindow("<p style='font-size:14px;'>考勤日期"+ i + "</p>");this.openInfoWindow(infoWindow);});map.addOverlay(marker);      } 

再看看正确的代码:

result = [...];  for(var i=0;i<result.length;i++){var marker = new BMap.Marker(new BMap.Point(result[i].coordx, result[i].coordy));   var date = result[i].date;(function(){var index = i;marker.addEventListener("click", function(e){var infoWindow = new BMap.InfoWindow("<p style='font-size:14px;'>考勤日期"+ index + "</p>");this.openInfoWindow(infoWindow);});})();map.addOverlay(marker);      } 

这里用到了js的一个特性:闭包,什么是闭包呢?可以参考http://hi.baidu.com/infol/item/edaef3d2b91eddfdca0c392b 这篇文章,讲的很详细。这里主要强调当看到闭包的时候,可以用对象的方式去理解。

接下来分析一下上面两段代码,主要用到两个概念(1)作用域(2)变量生命周期:

for 循环里面是一个作用域这里相当与外围作用域,通过marker.addEventListener绑定的事件函数里面也有个作用域,由于后一个作用域里面引用了前一个作用域里声名的变量,导致循环完成后 i 没有被释放,一直存在于内存中。当我们触发单击事件的时候,循环早已经完成,此时的 i 的值是10。所以才会发生所有Infowindow的值都是:考勤日期10

第二段代码里把事件函数用(function(){...});匿名函数包围起来,相当于增加了一层作用域,我们知道匿名函数外面加括号相当于一个表达式,而表达式里面声名的变量在表达式结束后就释放了,所以能够取到正确的值。

 

 

 



 


 

原创粉丝点击