OpenLayers.Event就是一个工具类,封装了一些dom事件操作方法,兼容性及操作更好点,比如stop、preventDefault、observe注册事件等等
重点是OpenLayers.Events
//支持的浏览器事件
BROWSER_EVENTS: [
"mouseover", "mouseout",
"mousedown", "mouseup", "mousemove",
"click", "dblclick", "rightclick", "dblrightclick",
"resize", "focus", "blur",
"touchstart", "touchmove", "touchend",
"keydown"
],
很多东西看api、源码注释就了解的差不多了,例如
includeXY: false
注意,这不是经纬度坐标,而是屏幕相对于map的屏幕坐标
源码中解释Should the .xy property automatically be created for browser
* mouse events?//xy属性是否应该包含在event的属性之中;
例如Map.js中
this.events = new OpenLayers.Events(
this, this.viewPortDiv, null, this.fallThrough,
{includeXY: true}
);
也就是说,map对象的事件中都可以用event.xy获取
具体使用方法看MousePosition.js这个control
this.map.events.register('mousemove', this, this.redraw);//注册mousemove事件
redraw: function(evt) {
var lonLat;
if (evt == null) {
this.reset();
return;
} else {
if (this.lastXy == null ||
Math.abs(evt.xy.x - this.lastXy.x) > this.granularity ||
Math.abs(evt.xy.y - this.lastXy.y) > this.granularity)
{
this.lastXy = evt.xy;
return;
}
lonLat = this.map.getLonLatFromPixel(evt.xy);
...........
}
},
什么事件需要自己触发,什么事件需要手动触发(自己写代码)?
大概也能猜到,浏览器事件是不需要自己写的,对,只要是BROWSER_EVENTS事件中的都可以按浏览器事件触发
看initialize构造函数中最后一段
if (element != null) {
this.attachToElement(element);
}
attachToElement: function (element) {
......
for (var i = 0, len = this.BROWSER_EVENTS.length; i < len; i++) {
type = this.BROWSER_EVENTS[i];
// register the event cross-browser
OpenLayers.Event.observe(element, type, this.eventHandler
);
.....
},
就是说,这些事件,你不需要手动触发的,当你绑定一个element时,这些事件也就已经在监听了
浏览器是如何监视和触发事件
注册事件有两种方式:register和on方法
源码中有解释
events.on({
"loadstart": loadStartListener,
"loadend": loadEndListener,
scope: object
});
// this is equivalent to the following
events.register("loadstart", object, loadStartListener);
events.register("loadend", object, loadEndListener);
这些事件时如何触发的呢?
还是看Map.js中有这么一段代码:
this.events.triggerEvent("addlayer", {layer: layer});
layer.events.triggerEvent("added", {map: this, layer: layer});
触发事件的方法是triggerEvent,同时需要注意的是,这些自定义的事件需要绑定一个对象,显然不是dom elment,而是这些js对象map、layer等等
triggerEvent: function (type, evt) {
var listeners = this.listeners[type];
// fast path
if(!listeners || listeners.length == 0) {
return undefined;
}
// prep evt object with object & div references
if (evt == null) {
evt = {};
}
evt.object = this.object;
evt.element = this.element;
if(!evt.type) {
evt.type = type;
}
// execute all callbacks registered for specified type
// get a clone of the listeners array to
// allow for splicing during callbacks
listeners = listeners.slice();
var continueChain;
for (var i=0, len=listeners.length; ivar callback = listeners[i];
// bind the context to callback.obj
continueChain = callback.func.apply(callback.obj, [evt]);
if ((continueChain != undefined) && (continueChain == false)) {
// if callback returns false, execute no more callbacks.
break;
}
}
它会找到通过listeners找到这个所有的这个事件对应的方法,然后执行
假如注册同一个事件,两次会怎么样呢?
并不会冲突,注册几次执行几次;如果方法返回false,则不会执行其后的事件函数
function init(){
map = new OpenLayers.Map( 'map');
layer = new OpenLayers.Layer.OSM( "Simple OSM Map");
map.addLayer(layer);
map.setCenter(
new OpenLayers.LonLat(-71.147, 42.472).transform(
new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()
), 12
);
map.events.on({"test":testMethod});
map.events.on({"test":testMethod2});
map.events.triggerEvent("test", {});
}
function testMethod(){
alert("testMethod");
//返回false,则后注册的方法不会执行
//return false;
}
function testMethod2(){
alert("testMethod2");
}
源码
for (var i=0, len=listeners.length; i<len; i++) {
var callback = listeners[i];
// bind the context to callback.obj
continueChain = callback.func.apply(callback.obj, [evt]);
if ((continueChain != undefined) && (continueChain == false)) {
// if callback returns false, execute no more callbacks.
break;
}
}