循环输出BMap.Marker标记

1 篇文章 0 订阅

要在地图上循环输出标记并给标记添加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(){...});匿名函数包围起来,相当于增加了一层作用域,我们知道匿名函数外面加括号相当于一个表达式,而表达式里面声名的变量在表达式结束后就释放了,所以能够取到正确的值。

 

 

 



 


 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值