關于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的時候傳入的參數中,注冊的事件都是來自于這個常量中的