地圖的事件與網頁事件:
常用的網頁事件主要由瀏覽器事件,如onload,或是用戶交互事件,如onclick, onhover等
地圖的事件也有用戶交互事件,如點擊事件等,還有地圖渲染相關的如postcompose(所有圖層加載完畢),postrender(地圖渲染完成)
能夠觸發事件的對象EventTarget 是一個接口,由可以接收事件、並且可以創建偵聽器的對象實現。
簡單實現如下:
var EventTarget = function() {
this.listeners = {};
};
EventTarget.prototype.listeners = null;
// 添加監視器
EventTarget.prototype.addEventListener = function(type, callback) {
if(!(type in this.listeners)) {
this.listeners[type] = [];
}
this.listeners[type].push(callback);
};
// 移除監視器
EventTarget.prototype.removeEventListener = function(type, callback) {
if(!(type in this.listeners)) {
return;
}
var stack = this.listeners[type];
for(var i = 0, l = stack.length; i < l; i++) {
if(stack[i] === callback){
stack.splice(i, 1);
return this.removeEventListener(type, callback);
}
}
};
// 觸發監視器
EventTarget.prototype.dispatchEvent = function(event) {
if(!(event.type in this.listeners)) {
return;
}
var stack = this.listeners[event.type];
event.target = this;
for(var i = 0, l = stack.length; i < l; i++) {
stack[i].call(this, event);
}
};
監聽地圖瀏覽事件的邏輯:
添加監視事件將回調函數存起來,當發生對應的行為(鼠標事件,對象屬性變更),則觸發對應的監視器,即執行對應的回調函數。
那么在openlayer中是如何將地圖和瀏覽器事件關聯在一起的呢?
綁定:
map類實例化的時候會用變量mapBrowserEventHandler_保存EventTarget的實例,並默認添加常用的瀏覽事件;
現在添加了對應的監視事件,並有對應的回調事件,那么如何在瀏覽器上觸發呢?
觸發:
1、地圖初始化的時候會在viewport也就是一個div上綁定pointerdown和pointerdrag等方法,pointerdown事件會監聽發生在地圖視圖上的點擊事件,pointerdrag會監視地圖拖拽事件
2、當在地圖容器的div上觸發對應的鼠標事件是,則會觸發對應的回調函數
監聽渲染事件的邏輯:
上面的監聽事件為地圖容器的鼠標事件,下面來看下地圖Map的渲染事件,如在所有的圖層加載完成會觸發postcompose事件
綁定:Map對象會有一個render_屬性用來保存圖層的渲染器對象,這個對象默認添加渲染事件的監視。
觸發:每次地圖的渲染事件觸發的時候,都會做一個判斷,獲取當前Map中所有的Layer數據源的loading狀態,當所有的loading都為false的時候,則觸發postcompose事件。
監聽屬性變化的邏輯:
Map對象可以監聽到view,size,layerGroup等的變化,那么是如何監聽的呢?
當手動改變view,size,layerGroup的時候,會調用set方法,set方法會觸發notify函數,notify函數中會觸發對應的事件回調。
// 通知
notify(key, oldValue) {
let eventType;
eventType = getChangeEventType(key);
this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
eventType = ObjectEventType.PROPERTYCHANGE;
this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
}
// 設置Map屬性
set(key, value, opt_silent) {
if (opt_silent) {
this.values_[key] = value;
} else {
const oldValue = this.values_[key];
this.values_[key] = value;
if (oldValue !== value) {
this.notify(key, oldValue);
}
}
}
