百度地圖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),
11);
map.addEventListener('click',
function(){
alert('您點選了地圖');
});
在初始化地圖完成後,我們通過map對象的addEventListener方法添加click事件的監聽。凡是在類參考文檔中說明某個類具備某些事件時,我們都可以調用該對象的addEventListener方法添加響應的事件監聽函數。
上面我們通過傳入一個匿名函數添加了事件監聽,如果我們需要移除事件監聽,則需要将監聽函數用具名函數表示:
var clickHandler
=function(){
}
map.addEventListener('click', clickHandler);
// 後續進行移除
map.removeEventListener('click', clickHandler);
事件參數
和DOM事件類似,在百度地圖API的事件機制中也提供了事件參數,參數通過監聽函數的參數進行傳遞,比如我們修改最開始的代碼:
function(e){
alert('點選坐标:
'+ e.point.lng
+',
'+ e.point.lat);
通過API的類參考文檔得知,click事件的參數包含type、target、point和pixel四個屬性,上面的示例就是擷取了point屬性,它表示目前點選的地理位置。
this
在事件監聽中還可以通過this引用觸發事件的對象,就像标準的DOM事件一樣。
map.addEventListener('dragend',
alert(this.getCenter());
// 這裡的this就是map執行個體
事件閉包
閉包是Javascript腳本語言的特性之一,不熟悉它的開發者很可能犯下面這種錯誤:頁面有十個标注(Marker執行個體),我希望點選不同的标注開啟内容不同的資訊視窗,每個資訊視窗顯示該标注的索引(1到10)。首先我們初始化标注執行個體并存放于數組中:
var markers
= [];
for (var i
=0; i
<10; i
++) {
var mkr
=new BMap.Marker(new BMap.Point(116.2+
i /20,
39.855), {title: i
+1});
markers.push(mkr);
map.addOverlay(mkr);
我們給每個标注添加自己的title屬性以示區分,你将看到如下效果:
下面,我們添加标注的點選事件,用來開啟内容不同的資訊視窗:
for (i
markers[i].addEventListener('click',
this.openInfoWindow(new BMap.InfoWindow('我是第'+
(i +1)
+'個标注'));
代碼看起來沒有任何問題,循環周遊markers數組,為每個标注執行個體綁定click事件,事件處理函數中開啟資訊視窗并顯示是第幾個标注。但是通過浏覽器看效果的時候卻發現問題了:
明明是第三個标注,點選之後的資訊視窗中卻顯示“11”。實際上,當click的監聽函數被執行的時候才會去看變量i的值是什麼,此時for循環早已經執行完,那麼當for循環執行完i的值正好是11。為了達到我們想要的效果,需要增加一層“閉包”:
(function(){
var index
= i;
(index +1)
})();
上面的代碼你可以了解為新增加的函數内部儲存了每次循環變量i的值,那麼當監聽函數執行時将會擷取閉包内儲存的index變量的值,而不是之前的變量i的值。再看一下,效果OK了:
對地圖API事件增強
我們通過幾個例子來看一下它的使用方法,首先需要引用這個js腳本,這裡就直接使用github提供的原始資料的位址:
https://raw.github.com/jiazheng/EventWrapper/master/release/eventwrapper.min.js
下面我們添加兩個事件監聽:
var clickListener
= EventWrapper.addListener(map,
'click',
alert(e.point.lng +',
var dragListener
'dragend',
移除的方式如下:
EventWrapper.removeListener(dragListener);
我們将之前addListener方法傳回的對象傳遞給removeListener即可,這和google的使用方式一緻。此外我們還可以清除某個對象所有通過此方式綁定的事件:
EventWrapper.clearInstanceListeners(map);
// 清除map執行個體所有的事件監聽函數
目前此項目基本完成,但是還沒有經過大規模的測試和驗證,可能存在不完善的地方,也歡迎廣大開發者發現問題并進行回報。
from:http://www.cnblogs.com/jz1108/archive/2011/07/16/2107199.html