OpenLayers源码学习:Map事件监视

地图的事件与网页事件:

常用的网页事件主要由浏览器事件,如onload,或是用户交互事件,如onclick, onhover等
地图的事件也有用户交互事件,如点击事件等,还有地图渲染相关的如postcompose(所有图层加载完毕),postrender(地图渲染完成)

能够触发事件的对象EventTarget 是一个接口,由可以接收事件、并且可以创建侦听器的对象实现。

简单实现如下:

var EventTarget = function() {
  this.listeners = {};
};

EventTarget.prototype.listeners = null;

// 添加监视器
EventTarget.prototype.addEventListener = function(type, callback) {
  if(!(type in this.listeners)) {
    this.listeners[type] = [];
  }
  this.listeners[type].push(callback);
};

// 移除监视器
EventTarget.prototype.removeEventListener = function(type, callback) {
  if(!(type in this.listeners)) {
    return;
  }
  var stack = this.listeners[type];
  for(var i = 0, l = stack.length; i < l; i++) {
    if(stack[i] === callback){
      stack.splice(i, 1);
      return this.removeEventListener(type, callback);
    }
  }
};

// 触发监视器
EventTarget.prototype.dispatchEvent = function(event) {
  if(!(event.type in this.listeners)) {
    return;
  }
  var stack = this.listeners[event.type];
  event.target = this;
  for(var i = 0, l = stack.length; i < l; i++) {
      stack[i].call(this, event);
  }
};

监听地图浏览事件的逻辑:

添加监视事件将回调函数存起来,当发生对应的行为(鼠标事件,对象属性变更),则触发对应的监视器,即执行对应的回调函数。

那么在openlayer中是如何将地图和浏览器事件关联在一起的呢?

绑定:
map类实例化的时候会用变量mapBrowserEventHandler_保存EventTarget的实例,并默认添加常用的浏览事件;

现在添加了对应的监视事件,并有对应的回调事件,那么如何在浏览器上触发呢?

触发:
1、地图初始化的时候会在viewport也就是一个div上绑定pointerdown和pointerdrag等方法,pointerdown事件会监听发生在地图视图上的点击事件,pointerdrag会监视地图拖拽事件
2、当在地图容器的div上触发对应的鼠标事件是,则会触发对应的回调函数

监听渲染事件的逻辑:

上面的监听事件为地图容器的鼠标事件,下面来看下地图Map的渲染事件,如在所有的图层加载完成会触发postcompose事件

绑定:Map对象会有一个render_属性用来保存图层的渲染器对象,这个对象默认添加渲染事件的监视。

触发:每次地图的渲染事件触发的时候,都会做一个判断,获取当前Map中所有的Layer数据源的loading状态,当所有的loading都为false的时候,则触发postcompose事件。

监听属性变化的逻辑:

Map对象可以监听到view,size,layerGroup等的变化,那么是如何监听的呢?

当手动改变view,size,layerGroup的时候,会调用set方法,set方法会触发notify函数,notify函数中会触发对应的事件回调。

  // 通知
  notify(key, oldValue) {
    let eventType;
    eventType = getChangeEventType(key);
    this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
    eventType = ObjectEventType.PROPERTYCHANGE;
    this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
  }

  // 设置Map属性
  set(key, value, opt_silent) {
    if (opt_silent) {
      this.values_[key] = value;
    } else {
      const oldValue = this.values_[key];
      this.values_[key] = value;
      if (oldValue !== value) {
        this.notify(key, oldValue);
      }
    }
  }
posted @ 2020-08-31 13:56  mangata  阅读(1428)  评论(0编辑  收藏  举报