OpenLayers中对 Map的事件 的使用和分析
http://www.cnblogs.com/lei3389/archive/2009/04/07/1430922.html
?
Map这个类提供了很多的事件可以让我们使用,本文说的就是如何使用以及对这部分源代码分析,关于openlayers的事件网上有很多的分析。
如何使用:
var map;
// define custom map event listeners
??????????????? function mapEvent(event) {
??????????????????? log(event.type);
??????????????? }
??????????????? function mapBaseLayerChanged(event) {
??????????????????? log(event.type + " " + event.layer.name);
??????????????? }
??????????????? function mapLayerChanged(event) {
??????????????????? log(event.type + " " + event.layer.name + " " + event.property);
??????????????? }
??????????????? map = new OpenLayers.Map('map', {
??????????????????? eventListeners: {
??????????????????????? "moveend": mapEvent,
??????????????????????? "zoomend": mapEvent,
??????????????????????? "changelayer": mapLayerChanged,
??????????????????????? "changebaselayer": mapBaseLayerChanged
??????????????????? }
??????????????? });
??????????????? 即,初始化的时候传入map的构造函数一个object,这个object中有个属性:
??????????????? eventListeners【其实是个哈希表】
看来我们要看map类的构造函数了。
---------------------------------------
---------------------------------------
进入map类,看构造函数
??? /**
???? * Constructor: OpenLayers.Map
???? * Constructor for a new OpenLayers.Map instance.
???? *
???? * Parameters:
???? * div - {String} Id of an element in your page that will contain the map.
???? * options - {Object} Optional object with properties to tag onto the map.
???? *
???? * Examples:
???? * (code)
???? * // create a map with default options in an element with the id "map1"
???? * var map = new OpenLayers.Map("map1");
???? *
???? * // create a map with non-default options in an element with id "map2"
???? * var options = {
???? *???? maxExtent: new OpenLayers.Bounds(-200000, -200000, 200000, 200000),
???? *???? maxResolution: 156543,
???? *???? units: 'm',
???? *???? projection: "EPSG:41001"
???? * };
???? * var map = new OpenLayers.Map("map2", options);
???? * (end)
???? */???
??? initialize: function (div, options)
??? 构造函数中进行初始化
??? 首先有一句:
??????????? // now override default options
??????? OpenLayers.Util.extend(this, options);
??????? Util.extend函数的作用可以理解为:是把第二个参数的属性方法都传给第一个参数
??????? 现在我们看刚才传入的带有eventListeners属性的object
??????? 我们传入的object给了options,则object中的eventListeners就传给了this.eventListeners
??????? 就是map类中的eventListeners属性
??? 来看这个属性的定义:
?????? /**
???? * APIProperty: eventListeners
???? * {Object} If set as an option at construction, the eventListeners
???? *???? object will be registered with <OpenLayers.Events.on>.? Object
???? *???? structure must be a listeners object as shown in the example for
???? *???? the events.on method.
???? */
??? eventListeners: null,
注释中说这个属性中的东西将通过OpenLayers.Events.on注册上,等会再说
同时指出这个对象必须是个“listeners object”的结构,其实就是我们前面传入的参数的eventListeners的结构
!!这里要注意了,listeners object是整个事件机制中的核心,所有的事件都是注册到他里面,然后触发的时候也是查找这个listeners object,找到里面注册的函数然后执行
goon..
构造函数中下面开始在map中初始化自己的events属性:
this.events = new OpenLayers.Events(this,
??????????????????????????????????????????? this.div,
??????????????????????????????????????????? this.EVENT_TYPES,
??????????????????????????????????????????? this.fallThrough,
??????????????????????????????????????????? {includeXY: true});
再往下就注册了:
if(this.eventListeners instanceof Object) {
??????????? this.events.on(this.eventListeners);
??????? }
通过map自己的Events属性(其实也是个object,就是events类的实例)中的on这个函数注册上,
我们要进入OpenLayers.Events类
---------------------------------------
---------------------------------------
看这个on方法
?? /**
???? * Method: on
???? * Convenience method for registering listeners with a common scope.
???? *
???? * Example use:
???? * (code)
???? * events.on({
???? *???? "loadstart": loadStartListener,
???? *???? "loadend": loadEndListener,
???? *???? scope: object
???? * });
???? * (end)
???? */
??? on: function(object) {
??????? for(var type in object) {
??????????? if(type != "scope") {
??????????????? this.register(type, object.scope, object[type]);
??????????? }
??????? }
??? },
on这个函数参数还是第一步中我们传入的eventListeners,就是那个哈希表
遍历,这个“scope”键值是事件的“产生源”对象,就是这个键值对应的对象触发我们注册的事件
register(type, object.scope, object[type])
type就是事件名称
object[type]就是处理事件的函数名
可以看一下第一步中传入的参数:
eventListeners: {
??????????????????????? "moveend": mapEvent,
??????????????????????? "zoomend": mapEvent,
??????????????????????? "changelayer": mapLayerChanged,
??????????????????????? "changebaselayer": mapBaseLayerChanged
??????????????????? }
再进入events类的另一个函数:this.register(type, object.scope, object[type])
?? /**
???? * APIMethod: register
???? * Register an event on the events object.
???? *
???? * When the event is triggered, the 'func' function will be called, in the
???? * context of 'obj'. Imagine we were to register an event, specifying an
???? * OpenLayers.Bounds Object as 'obj'. When the event is triggered, the
???? * context in the callback function will be our Bounds object. This means
???? * that within our callback function, we can access the properties and
???? * methods of the Bounds object through the "this" variable. So our
???? * callback could execute something like:
???? * :??? leftStr = "Left: " + this.left;
???? *??
???? *?????????????????? or
???? *?
???? * :??? centerStr = "Center: " + this.getCenterLonLat();
???? *
???? * Parameters:
???? * type - {String} Name of the event to register
???? * obj - {Object} The object to bind the context to for the callback#.
???? *???????????????????? If no object is specified, default is the Events's
???? *???????????????????? 'object' property.
???? * func - {Function} The callback function. If no callback is
???? *??????????????????????? specified, this function does nothing.
???? *
???? *
???? */
??? register: function (type, obj, func) {
??????? if ( (func != null) &&
???????????? (OpenLayers.Util.indexOf(this.eventTypes, type) != -1) ) {
??????????? if (obj == null)? {
??????????????? obj = this.object;
??????????? }
??????????? var listeners = this.listeners[type];
??????????? listeners.push( {obj: obj, func: func} );
??????? }
??? },
到这里,我们能看到我们所说的核心,那个哈希表,把自己的值都赋给了events类的一个属性:listeners
? /**
???? * Property: listeners
???? * {Object} Hashtable of Array(Function): events listener functions?
???? */
??? listeners: null,
这个事件机制的核心哈希表,键名就是事件的名称,也就是参数中的type,键值是一个对象{obj: obj, func: func}
当然这个对象中还有对象。。。。
现在事件已经注册上了,还有一个问题,register函数中提到了this.eventTypes,this.object
所以我们再回来看下events类的构造函数。
map类中实例化events属性的情景:
this.events = new OpenLayers.Events(????this, //指的是map
??????????????????????????????????????????? this.div,
??????????????????????????????????????????? this.EVENT_TYPES,
??????????????????????????????????????????? this.fallThrough,
??????????????????????????????????????????? {includeXY: true});
我们可以和events类的构造函数对比一下参数,就会明白了?
?? /**
???? * Constructor: OpenLayers.Events
???? * Construct an OpenLayers.Events object.
???? *
???? * Parameters:
???? * object - {Object} The js object to which this Events object? is being
???? * added element - {DOMElement} A dom element to respond to browser events
???? * eventTypes - {Array(String)} Array of custom application events
???? * fallThrough - {Boolean} Allow events to fall through after these have
???? *???????????????????????? been handled?
???? * options - {Object} Options for the events object.
???? */
??? initialize: function (
??? ???????????????object,
??? ???????????????element,
??? ???????????????eventTypes,
??? ???????????????fallThrough,
??? ???????????????options)
??? ??{
??????? OpenLayers.Util.extend(this, options);
??????? this.object???? = object;
??????? this.element??? = element;
??????? this.fallThrough = fallThrough;
??????? this.listeners? = {};
??????? // keep a bound copy of handleBrowserEvent() so that we can
??????? // pass the same function to both Event.observe() and .stopObserving()
??????? this.eventHandler = OpenLayers.Function.bindAsEventListener(
??????????? this.handleBrowserEvent, this
??????? );
??????? // if eventTypes is specified, create a listeners list for each
??????? // custom application event.
??????? this.eventTypes = [];
??????? if (eventTypes != null) {
??????????? for (var i=0, len=eventTypes.length; i<len; i++) {
??????????????? this.addEventType(eventTypes[i]);
??????????? }
??????? }
???????
??????? // if a dom element is specified, add a listeners list
??????? // for browser events on the element and register them
??????? if (this.element != null) {
??????????? this.attachToElement(element);
??????? }
??? },
?上面events的初始化是发生在map的初始化中,this.events.on(this.eventListeners);之前的,所以上面提到的register函数中的this.eventTypes,this.object 就明确意思了:
?this.object(this是指的events类)就是map,也就是说map是我们第一步传入参数中的注册事件的“发生源”,(比如button是onclik的“发生源”,“发生源”是本人自定义的。。不知道是否有合适的称呼,术语应该就是srcElement)
this.eventTypes(this是指的events类)就是map类中定义的一个常量:this.EVENT_TYPES(this是指的map类)
查到map类中的这个常量 EVENT_TYPES: [
??????? "preaddlayer", "addlayer", "removelayer", "changelayer", "movestart",
??????? "move", "moveend", "zoomend", "popupopen", "popupclose",
??????? "addmarker", "removemarker", "clearmarkers", "mouseover",
??????? "mouseout", "mousemove", "dragstart", "drag", "dragend",
??????? "changebaselayer"],
所以我们在初始化map的时候传入的参数中,注册的事件都是来自于这个常量中的