javascript設計模式(張容銘)學習筆記 - 外觀模式綁定事件

有一個需求要爲document對象綁定click事件來是想隱藏提示框的交互功能,因而小白寫了以下代碼:瀏覽器

document.onclick = function(e) {
  e.preventDefault();
  if(e.target !== document.getElementById('myinput')) {
    hidePageAlert();
  }
}


function hidePageAlert() {
  //隱藏提示框
}

同事小銘看了看代碼說:dom

「首先,你爲document 綁定了click事件,可是onclick是DOM0級事件,也就是說這種方式綁定的時間至關於爲元素綁定了一個時間方法, 因此若是團隊中的其餘人再次經過這種方式爲document綁定click事件時,就至關於重複定義了一個方法,會將你定義的click事件方法覆蓋,以下列程序。」ide

document.onclick= function() {
  //其餘開發人員從新爲document綁定時間會覆蓋前面定義的DOM0級click事件
}

「因此你這種方式是很危險的。所以你應該用DOM2級事件處理程序提供的方法addEventListener來實現,然而你知道老版本的IE瀏覽器(低於9)是不支持這個方法的,它支持的是attachEvent,固然若是有不支持DOM2級事件處理程序的瀏覽器,你只能用onclick事件方法來綁定事件。」spa

「那麼有沒有一個兼容全部瀏覽器的方式呢?」 小白追問。code

兼容模式對象

// 外觀模式實現

function addEvent(dom, type, fn) {
  // 對於支持DOM2級事件處理程序addEventListener方法的瀏覽器
  if(dom.addEventListener) {
    dome.addEventListener(type, fn, false);
  // 對於不支持addEventListener 方法,可是支持attachEvent方法的瀏覽器
  }else if(dom.attachEvent) {
    dom.attachEvent('on' + type, fn);
  // 對於不支持addEventListener方法也不支持attachEvent方法,但支持on+'事件名'的瀏覽器
  }else{
     dom['on' + type] = fn;
  }
}

「這樣咱們之後對於支持addEventListener 或 attachEvent方法的瀏覽器就能夠放心的綁定多個事件了, 以下所示。」blog

var myInput = document.getElementById('myinput');

addEvent(myInput, 'click', function(){
  console.log('綁定第一個事件')
})

addEvent(myInput, 'click', function(){
  console.log('綁定第二個事件')
})

 

除此以外接口

「不過以前寫的代碼問題不止一個,以前說了,外觀模式能夠簡化底層接口複雜性,也能夠解決瀏覽器兼容性問題。而你以前寫的代碼除了綁定時間的問題外,另外兩處問題是在其餘IE低版本瀏覽器中不兼容 e.preventDefault 和 e.target。你也能夠經過外觀模式來解決。」事件

 

// 獲取事件對象
var getEvent = function(event) {
  // 標準瀏覽器返回event,IE下window.event
  return event || window.event;
}

// 獲取元素
var getTarget = function(event) {
  var event = getEvent(event);
  // 標準瀏覽器下event.target, IE下event.srcElement
  return event.target || event.srcElement;
}

// 阻止默認行爲
var preventDefault = function(event) {
  var event = getEvent(event);
  // 標準瀏覽器
  if(event.preventDefault) {
    event.preventDefault();
  // IE 瀏覽器
  }else {
    event.returnValue = false;
  }
}

「有了上面的方法,咱們就能夠用兼容的簡單方式來解決上面的問題。」開發

document.onclick = function(e) {
  // 阻止默認行爲
  preventDefault(e);
  // 獲取事件源目標對象
  if(getTarget(e) != document.getElementById('myinput')){
    hideInputSug();
  }
}
相關文章
相關標籤/搜索