概述
在源码分析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类中实现的。