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);
      }
    }
  }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM