原文:百度地图API详解之事件机制,function“闭包”解决for循环和监听器冲突的问题:

百度地图API详解之事件机制
2011年07月26日 星期二 下午 04:06

和DOM编程里的事件模型一样,百度地图API也提供了类似的事件机制。本文介绍了事件监听的添加和移除方法,this指针和事件参数的使用以及绑定事件监听函数中涉及的闭包问题,最后分享了一个用来增强地图API事件机制的开源项目。



事件添加和移除

我们最简单的事件开始,下面的代码示例给map对象添加了click事件的监听函数,当用户点击地图时该监听函数就会被触发:

var map
=new BMap.Map('map');

map.centerAndZoom(new BMap.Point(116.404,
39.915),
);



map.addEventListener('click',
function(){

alert('您点击了地图');

});

在初始化地图完成后,我们通过map对象的addEventListener方法添加click事件的监听。凡是在类参考文档中说明某个类具备某些事件时,我们都可以调用该对象的addEventListener方法添加响应的事件监听函数。

上面我们通过传入一个匿名函数添加了事件监听,如果我们需要移除事件监听,则需要将监听函数用具名函数表示:

var clickHandler
=function(){

alert('您点击了地图');

}



map.addEventListener('click', clickHandler);



// 后续进行移除

map.removeEventListener('click', clickHandler);



事件参数

和DOM事件类似,在百度地图API的事件机制中也提供了事件参数,参数通过监听函数的参数进行传递,比如我们修改最开始的代码:

map.addEventListener('click',
function(e){

alert('点击坐标:
'+ e.point.lng
+',
'+ e.point.lat);

});

通过API的类参考文档得知,click事件的参数包含type、target、point和pixel四个属性,上面的示例就是获取了point属性,它表示当前点击的地理位置。



this

在事件监听中还可以通过this引用触发事件的对象,就像标准的DOM事件一样。

map.addEventListener('dragend',
function(e){

alert(this.getCenter());
// 这里的this就是map实例

});



事件闭包

闭包是Javascript脚本语言的特性之一,不熟悉它的开发者很可能犯下面这种错误:页面有十个标注(Marker实例),我希望点击不同的标注开启内容不同的信息窗口,每个信息窗口显示该标注的索引(1到10)。首先我们初始化标注实例并存放于数组中:

var markers
= [];

for (var i
; i
; i
++) {

var mkr
=new BMap.Marker(new BMap.Point(116.2+
i ,
39.855), {title: i
});

markers.push(mkr);

map.addOverlay(mkr);

}

我们给每个标注添加自己的title属性以示区分,你将看到如下效果:

下面,我们添加标注的点击事件,用来开启内容不同的信息窗口:

for (i
; i
; i
++) {

markers[i].addEventListener('click',
function(){

this.openInfoWindow(new BMap.InfoWindow('我是第'+
(i )
+'个标注'));

});

}

代码看起来没有任何问题,循环遍历markers数组,为每个标注实例绑定click事件,事件处理函数中开启信息窗口并显示是第几个标注。但是通过浏览器看效果的时候却发现问题了:

明明是第三个标注,点击之后的信息窗口中却显示“11”。实际上,当click的监听函数被执行的时候才会去看变量i的值是什么,此时for循环早已经执行完,那么当for循环执行完i的值正好是11。为了达到我们想要的效果,需要增加一层“闭包”:

for (i
; i
; i
++) {

(function(){

var index
= i;

markers[i].addEventListener('click',
function(){

this.openInfoWindow(new BMap.InfoWindow('我是第'+
(index )
+'个标注'));

});

})();

}

上面的代码你可以理解为新增加的函数内部保存了每次循环变量i的值,那么当监听函数执行时将会获取闭包内保存的index变量的值,而不是之前的变量i的值。再看一下,效果OK了:



对地图API事件增强

熟悉google地图API的人可能知道,其事件相关的接口要比百度地图API的接口丰富,除了提供简单的addListener和removeListener之外,还提供了clearListeners、clearInstanceListeners、trigger等方法。那么这些功能在百度地图API中如何实现呢?实际上百度地图API的内部也有事件机制并且与对外公开的事件共用一套机制,如果API提供了诸如clearListeners的方法必然会对API内部的逻辑造成影响,因此也就没有提供类似的接口。如果开发者很喜欢google地图API的事件机制模式并且非用不可怎么办呢,没问题,这里和大家分享一个我的开源项目,名字暂定为EventWrapper,它基于百度地图API,但提供了类似google地图事件机制的接口形式。开源项目地址:https://github.com/jiazheng/EventWrapper。src目录下的main.js就是全部代码了,这是开发版本,如果直接使用可以获取release目录下的eventwrapper.min.js。

我们通过几个例子来看一下它的使用方法,首先需要引用这个js脚本,这里就直接使用github提供的原始数据的地址:

https://raw.github.com/jiazheng/EventWrapper/master/release/eventwrapper.min.js

下面我们添加两个事件监听:

var clickListener
= EventWrapper.addListener(map,
'click',
function(e){

alert(e.point.lng +',
'+ e.point.lat);

});

var dragListener
= EventWrapper.addListener(map,
'dragend',
function(e){

alert(e.point.lng +',
'+ e.point.lat);

});

移除的方式如下:

EventWrapper.removeListener(dragListener);

我们将之前addListener方法返回的对象传递给removeListener即可,这和google的使用方式一致。此外我们还可以清除某个对象所有通过此方式绑定的事件:

EventWrapper.clearInstanceListeners(map);
// 清除map实例所有的事件监听函数

此外EventWrapper还提供了addDomListener、addDomListenerOnce、addListenerOnce、clearListeners和trigger方法,具体使用方法可参考开发版本脚本中的注释信息(开发脚本原始数据地址:https://raw.github.com/jiazheng/EventWrapper/master/src/main.js)。

目前此项目基本完成,但是还没有经过大规模的测试和验证,可能存在不完善的地方,也欢迎广大开发者发现问题并进行反馈。

from:http://www.cnblogs.com/jz1108/archive/2011/07/16/2107199.html

百度地图API详解之事件机制,function“闭包”解决for循环和监听器冲突的问题:的更多相关文章

  1. [转]百度地图API详解之地图坐标系统

    博客原文地址:http://www.jiazhengblog.com/blog/2011/07/02/289/ 我们都知道地球是圆的,电脑显示器是平的,要想让位于球面的形状显示在平面的显示器上就必然需 ...

  2. 百度地图API详解之自定义地图类型

    http://blog.csdn.net/sup_heaven/article/details/8461586 今天的文章主要介绍如何利用地图API实现自定义地图. 百度地图API目前默认支持两种地图 ...

  3. 百度地图Api详解之地图标注

    标注概述 标注(Marker)是用来表示一个点位置的可见元素,每个标注自身都包含地理信息.比如你在西单商场位置添加了一个标注,不论地图移动.缩放,标注都会跟随一起移动,保证其始终指向正确的地理位置. ...

  4. iOS 百度地图使用详解

    最近仿照美团做了款应用,刚好用到百度地图,高德地图之前用的比较多,只是这个项目的后台服务器是另外一个公司做的,他们用的就是百度地图,现在网上用百度地图的还不算太多,博文也是断断续续的,主要是中间跳跃有 ...

  5. 百度地图API调用实例之地址标注与位置显示

    之前弄了个谷歌地图API标注的调用实例,后来要求改成百度地图. 感谢主,通过网上资料(百度地图API,百度地图API详解之地图标注)收集及研究, 终于把百度地图标注和显示功能实现出来了,具体实现方法如 ...

  6. 【百度地图API】如何自定义地图图层?实例:制作麻点图(自定义图层+热区)

    原文:[百度地图API]如何自定义地图图层?实例:制作麻点图(自定义图层+热区) 摘要:自定义地图图层的用途十分广泛.常见的应用,比如制作魔兽地图和清华校园地图(使用切图工具即可轻松实现).今天我们来 ...

  7. 百度地图API基本使用(一)

    本文系作者 chaoCode原创,转载请私信并在文章开头附带作者和原文地址链接. 违者,作者保留追究权利. 前言 由于最近项目有需要,所以最近开始研究百度地图API的使用,简单的介绍一下百度地图Jav ...

  8. 【百度地图API】如何给自定义覆盖物添加事件

    原文:[百度地图API]如何给自定义覆盖物添加事件 摘要: 给marker.lable.circle等Overlay添加事件很简单,直接addEventListener即可.那么,自定义覆盖物的事件应 ...

  9. 百度地图API如何给自定义覆盖物添加事件

    摘要: 给marker.lable.circle等Overlay添加事件很简单,直接addEventListener即可.那么,自定义覆盖物的事件应该如何添加呢?我们一起来看一看~ --------- ...

随机推荐

  1. RH033读书笔记(9)-Lab 10 Understanding the Configuration Tools

    Lab 10 Understanding the Configuration Tools Sequence 1: Configuring the Network with system-config- ...

  2. 高榕资本宾悦:未使用的企业家Testin云测试服务类故障

    高榕资本岳斌:创业者未使用Testin云測试服务属不合格 2014/10/09 · Testin · 开发人员訪谈 Testin云測与工信部等联合承办的ICT中国.2014高层论坛之移动开发人员分论坛 ...

  3. Swift学习笔记7:关闭

    闭包 捕 引用和将其存储在任意常量和变量的上下文. Swift 你会管理 捕获 过程中涉及到的内存操作. 在 函数 章节中介绍的全局和嵌套函数实际上也是特殊的闭包,闭包採取例如以下三种形式之中的一个: ...

  4. 2013成都邀请赛J称号||HDU4725 The Shortest Path in Nya Graph(spfa+slf最短的优化)

    职务地址:HDU 4725 这题卡了好长时间了,建图倒是会建,可是不会最短路的算法优化,本以为都须要堆去优化的,打算学了堆之后再来优化.可是昨晚CF的一道题..(那题也是不优化过不了..)然后我就知道 ...

  5. 【Shell剧本练习】得出的结论是当前用户

    推断是否当前用户root.假设是暗示root用户,假设而不是提示对于普通用户 #!/bin/bash #title: testus.sh #author: orangleliu #date: 2014 ...

  6. Snail—ORACLE基础之事务学习(五)

    ---------------事务---当运行到commit时 事务才算是完毕,不然 会运行rollback操作. declare v_money acount.money%type:=1223; e ...

  7. 程序猿常识--OJ系统和ACM测试考试大全

    OJ它是Online Judge缩写系统,来在线检測程序源码的正确性. 著名的OJ有RQNOJ.URAL等. 国内著名的题库有北京大学题库.浙江大学题库等. 国外的题库包含乌拉尔大学.瓦拉杜利德大学题 ...

  8. SVM算法实现(一)

    关键字(keywords):SVM 支持向量机 SMO算法 实现 机器学习 假设对SVM原理不是非常懂的,能够先看一下入门的视频,对帮助理解非常实用的,然后再深入一点能够看看这几篇入门文章,作者写得挺 ...

  9. 理解JNDI中 java:comp/env/jdbc/datasource 与 jdbc/datasource 的不同之处(转)

    在描述JNDI,例如获得数据源时,JNDI地址有两种写法,例如同是  jdbc/testDS 数据源: A:java:comp/env/jdbc/testDS B:jdbc/testDS   这两种写 ...

  10. JDK自带的监控分析工具JConsole

    非常多开发人员认为自己懂Java编程.事实是大多数开发人员都仅仅领会到了Java平台的皮毛.所学也仅仅够应付工作. 作者将深度挖掘Java平台的核心功能.揭示一些鲜为人知的事实.帮助您解决最棘手的编程 ...