JavaScript權威指南--事件處理

知識要點

客戶端JavaScript程序採用了異步事件驅動變成模型(13.3.2節)。這種風格並不僅應用於web編程,全部使用圖形用戶界面的應用程序都採用它,它們靜待某些事件發生,而後響應。javascript

事件就是web瀏覽器通知應用程序發生什麼事情。它不是JavaScript對象,不會出如今程序源代碼中。固然,有些事件相關的對象會出如今源代碼中。html

事件類型是一個用來講明發生什麼類型事件的字符串。因爲只是個字符串,因此也能夠叫事件名字。html5

事件目標是發生的事件或與之相關的對象。事件必須同時致命類型和目標。例如window上的load事件或<button>元素的click事件。在客戶端JavaScript中,Window、Document和Element對象是最多見的事件目標。有些事件是由其餘類型的對象觸發,例如18章的由XHR對象觸發的readystatechange事件。java

事件處理程序或事件監聽程序是處理或響應事件的函數。web

事件對象是與特定事件相關且包含有關該事件詳細信息的對象事件對象做爲參數傳遞給事件處理程序函數(IE8及之前版本不同)。全部事件對象都有用來指定事件類型的type屬性和指定事件目標的target屬性(IE8前的srcElement)。每一個事件類型都爲其相關事件對象定義一組屬性,例如鼠標事件有指針座標,不少只有type和target,沒有更詳細的屬性。編程

事件傳播是瀏覽器決定哪一個對象觸發其事件處理程序的過程。對於單個對象的特定事件(好比Window對象的load事件),必須是不能傳播的。當文檔元素髮生在某個類型的事件時,會發生冒泡,還有事件捕獲(IE8及之前不支持,因此少用)。瀏覽器

事件處理程序能夠經過返回一個適當的值、調用事件對象的某個方法或設置對象的某個屬性來阻止默認操做的發生。好比超連接的click事件能夠阻止加載新頁面。網絡

1.事件類型

1.1.傳統事件類型

表單事件異步

經過事件處理程序能取消submit和reset事件的默認操做,某些click事件也是如此。focus和blur事件不會冒泡,但其餘全部表單事件均可以。ie定義了focusin和focusout事件能夠冒泡,它們能夠用於替代focus和blur事件。函數

不管用戶什麼時候輸入文字(經過鍵盤或剪切和粘貼)到textarea和其餘文本輸入表單元素,除ie外的瀏覽器都會觸發input事件。不像change事件,每次文字插入都會觸發input事件,遺憾的是,input事件的事件對象沒有指定輸入文字的內容(textinput事件將會成爲這個事件的有用替代方案。)

Window事件

Window是指事件的發生與瀏覽器自己而非窗口中顯示的任何特定文檔內容相關,可是,這些事件中有一些會和文檔元素上發生的事件同名。

window對象的onerror屬性有點像事件處理程序,當javascript出錯時會觸發他。可是,它不是真正的事件處理程序,由於它能用不一樣的參數來調用(14.6節)。

像<img>元素這樣的單個文檔元素也能爲load和error事件註冊處理程序。當外部資源(例如圖片)徹底加載或發生阻止加載的錯誤時就會觸發它們。某些瀏覽器也支持也支持abort事件,當圖片(或其餘網絡資源)由於用戶中止加載進程而致使失敗就會觸發它.

鼠標事件

傳遞給鼠標事件處理的事件對象有屬性集,它們描述了當事件發生時鼠標的位置和按鍵狀態,也指明瞭當時是否有任何輔助鍵按下。clientX和clientY屬性指定了鼠標在窗口座標中的位置,button和which屬性指定了按下的鼠標鍵是哪一個。當鍵盤輔助鍵按下時,對應的屬性altkey、ctrlKey、metaKey和shiftKey會設置爲true。而對於click事件,detail屬性指定了其是單擊、雙擊仍是三擊。

鍵盤事件

不管任何文檔元素得到鍵盤焦點都會觸發鍵盤事件,而且他們會冒泡到Document和window對象。若是沒有元素得到焦點,能夠直接在文檔上觸發事件。傳遞給鍵盤事件處理程序的事件對象有keyCode字段。它指定按下或釋放的鍵是哪一個,除了keyCode,鍵盤事件對象也有altKey,ctrlKey、metaKey和shiftKey,描述鍵盤輔助建的狀態。

1.2.DOM事件

新DOM標準經過在事件對象中加入新的key和char屬性來簡化keydown、keyup和keypress事件,這些屬性都是字符串。

1.3.HTML5事件

離線web應用還定義了大量其餘事件來通知應用:

2.註冊事件處理程序

有兩種基本方式:第一種,給事件目標對象或文檔元素設置屬性。第二種方式,是將事件處理程序傳遞給對象或元素的一個方法,每種技術都有兩個版本。能夠在javascript代碼中設置事件處理程序爲對象屬性,或對於文檔元素,能夠在html中直接設置相應屬性。對於經過方法調用的處理程序註冊,有一個標準方法,命名爲addEventListener,除IE8及之前版本以外,全部瀏覽器都支持這個方式,而ie9以前的IE版本支持的是一個叫attachEvent的不一樣方法。

2.2.設置HTML標籤屬性爲事件處理程序

某些事件類型一般直接在瀏覽器而非任何特定文檔元素上觸發。在javascipt中,這些事件處理程序在window對象上註冊。在html中,會把他們放在body標籤上,但瀏覽器會在window對象上註冊它們

在指定一串JavaScript代碼做爲HTML事件處理程序屬性的值時,瀏覽器會把代碼串轉換爲相似以下的函數中:

function(event){
  with(document){
    with(this.form || {}){
      with(this){
        /*這裏是編碼*/
      }
    }
  }
}

3.事件處理程序的調用

3.1.事件處理程序的參數 

一般調用事件處理程序時把事件對象做爲他們的一個參數(有一個例外)。事件對象的屬性提供了有關事件的詳細信息,例如,type屬性指定了發生的類型。在IE8及之前版本中,經過設置屬性註冊處理程序,當調用它們時並未傳遞事件對象,取而代之,須要經過全局對象window.event來得到事件對象

function handler(event){
var event=event||window.event;
}

向使用attachEvent註冊的事件處理程序傳遞事件對象,但它們也能使用window.event。

17.2.2節,當經過設置HTML屬性註冊事件處理程序時,瀏覽器會把javascript編碼轉換到一個函數中。非IE瀏覽器使用event參數來構造函數,而IE在構造函數時沒有有要求參數。若是在這樣的函數中使用event標識符,那麼引用的正是Window.event.在這兩種狀況下,HTML事件處理程序都能做爲event引用事件對象。

3.2.事件處理程序的運行環境

當使用addEventListener註冊時,調用的處理程序使用事件目標做爲它們的this值。可是,對於attachEvent來說這是不對的:使用attachEvent註冊的處理程序做爲函數調用,它們的this值是全局對象(window)。能夠用以下代碼來解決這個問題:

/*
*在指定的事件目標上註冊用於處理指定類型事件的指定處理程序函數
*確保處理程序一直做爲事件目標的方法調用
*/
function addEvent(target,type,handler){
  if(target.addEventListener){
 target.addEventListener(type,handler,fasle);
  }
  else{
    target.attachEvent("on"+type,function(event){
      return handler.call(target,event);
      //把處理程序做爲事件目標的方法調用,傳遞事件對象
    })   
  }
}

注意使用這個方法註冊的事件處理程序不能刪除,由於傳遞給attchEvent的包裝函數沒有保留下來傳遞給detachEvent。

3.3.事件處理程序的做用域 

它們在其定義時的做用域而非調用時的做用域中執行,而且它們能存取那個做用域中的任何一個本地變量。可是經過HTML屬性來註冊事件處理程序是一個例外,它們被轉換爲能存取全局變量的頂級函數而非任何本地變量。可是因爲歷史緣由,它們運行在一個修改後的做用域鏈中,經過HTML屬性定義的事件處理程序能好像本地變量同樣使用目標對象,容器<form>對象(若是有)和Document對象的屬性。

HTML屬性最不天然的地方包括冗長的代碼串和修改會的做用域鏈容許有用的快捷方式,可使用tagName替代this.tagName,使用getElementById()替代document.getElementById()。而且,對於<form>中的文檔元素,能經過ID引用任何其餘的表單元素,例如zicode替代this.form.zipcode。

另外一方面,HTML事件處理程序中修改的做用域鏈是陷阱之源,由於做用域鏈中每一個對象的屬性在全局對象中都有相同名字的屬性。例如Document對象定義(不多使用)open()方法,所以HTML事件處理程序想調用Window對象的open方法就必須顯示地調用window.open而不是open。表單有相似的問題但破壞性更大,由於表達元素的名字和ID在包含的表單元素上定義屬性。例如表單包含一個ID是「location」的元素,那麼要是表單的全部HTML事件處理程序想引用window的location對象,就必須使用window.location而不能是location。

3.4.事件處理程序的返回值

經過設置對象屬性或HTML屬性註冊事件處理程序的返回值有時是很是有意義的。

3.7.事件取消

function cancelHandle(event){
  var event = event || window.event;//用於IE
  /*處理事件的代碼*/
  //取消默認行爲
  if(event.preventDefault)event.preventDefault();
  if(event.returnValue)event.returnValue = false;
  return false;  //用於處理使用對象屬性註冊的處理程序
}

5.鼠標事件

7.拖放事件 

http://www.w3school.com.cn/html5/html_5_draganddrop.asp

相關文章
相關標籤/搜索