地图的事件与网页事件:
常用的网页事件主要由浏览器事件,如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);
}
}
}