您的位置:首页 > 运维架构

OpenLayers2 源码解读 事件Event、Events

2016-07-09 21:58 381 查看
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; 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;
}
}


它会找到通过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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  openlayers 事件 event ol2