概述
在源码分析Openlayers默认键盘交互实现文中介绍了KeyboardZoom
和 KeyboardPan
的实现,它们都是继承Interaction
类,封装了自己的handleEvent
方法,该方法接受一个mapBrowserEvent
参数,计算出地图视图的变化量,最后调用view
的animate
方法实现地图的缩放或平移。
本文将介绍Openlayers是如何实现Interaction
类,以及键盘事件流的全过程即如何映射到Openlayers的自定义事件。
源码剖析
defaultsInteractions
入口函数
当实例化一个地图,即new Map(options)
时,会调用一个内部方法createOptionsInternal
,该方法接受options
参数经过一些处理,返回一个新的变量,如下:
function createOptionsInternal(options){/**.... **/let interactions;if (options.interactions !== undefined) {if (Array.isArray(options.interactions)) {interactions = new Collection(options.interactions.slice());} else {assert(typeof (/** @type {?} */ (options.interactions).getArray) ==='function','Expected `interactions` to be an array or an `ol/Collection.js`',);interactions = options.interactions;}}return {controls: controls,interactions: interactions,keyboardEventTarget: keyboardEventTarget,overlays: overlays,values: values,};
}
由此可知,如果参数options
对象的interactions
值为空,则createOptionsInternal
内部不对其有任何处理,在Map
的构造函数里会有如下的判断:
const optionsInternal = createOptionsInternal(options);this.interactions =optionsInternal.interactions ||defaultInteractions({onFocusOnly: true,});
在构造内部给optionsInternal
变量赋值后,会判断它的interactions
是否存在,如果不存在,则调用defaultsInteractions
,这个方法就是决定了Openlayers 采用默认的交互事件的入口函数。
interactions
键盘事件监听
构造函数Map
内部会调用this.addChangeListener(MapProperty.TARGET, this.handleTargetChanged_);
添加map.target
变化的监听函数handleTargetChanged_
构造函数Map
是继承于BaseObject
类,在BaseObject
类中会调用自己定义的setProperties
方法,然后遍历参数values
,调用set
方法,并在其内部调用notify
方法,如果事件类型eventType
有监听,则调用dispatchEvent
方法去派发事件,BaseObject
类是继承了Observable
类,而Observable
类又是继承了EventTarget
类,dispatchEvent
就是在EventTarget
类中实现的。