javascript事件概述

事件基本概念

事件類型:用來說明發(fā)生什么類型事件的字符串,即事件名。
  事件目標(biāo):發(fā)生事件的對象。當(dāng)談?wù)撌录r,會同時指明類型和目標(biāo)。
  事件處理程序:處理或響應(yīng)事件的函數(shù),即事件監(jiān)聽程序。
  事件對象:與特定事件相關(guān)并且包含有關(guān)該事件詳細(xì)信息的對象。事件對象作為參數(shù)傳遞給事件處理程序(IE8之前的瀏覽器通過Event獲取事件對象)。
  事件傳播:事件發(fā)生時,事件會由window發(fā)出,不斷經(jīng)過下一級節(jié)點直到目標(biāo)節(jié)點,到達目標(biāo)節(jié)點后,事件會按原路線返回window,事件從目標(biāo)節(jié)點返回window的過程就是事件傳播,又稱冒泡階段。在事件傳播階段可以通過事件對象阻止事件傳播。
  事件捕獲: 事件發(fā)生時,事件會由window發(fā)出,不斷經(jīng)過下一級節(jié)點直到目標(biāo)節(jié)點,這一過程就是事件捕獲,又稱捕獲階段。在事件捕獲階段可以通過事件對象阻止事件捕獲。IE8之前的瀏覽器不支持事件捕獲。

常見事件類型

1.Window事件
  發(fā)生在瀏覽器窗口上的事件,部分事件的事件類型會與文檔中的某些事件類型同名,包括文檔以及外部資源完全加載時觸發(fā)的load事件;瀏覽器窗口文檔跳轉(zhuǎn)到新文檔時觸發(fā)unload事件,該事件觸發(fā)時不影響文檔跳轉(zhuǎn);在文檔跳轉(zhuǎn)之前如果需要征得用戶同意,可以使用beforeunload事件;瀏覽器窗口加載文檔過程中出錯時觸發(fā)error事件;瀏覽器窗口尺寸改變時觸發(fā)resize事件,滾動條滾動時觸發(fā)scroll事件;瀏覽器窗口獲取焦點或者失去焦點時,分別觸發(fā)focus事件,blur事件;
  2.DOM事件
  主要有表單事件,鼠標(biāo)事件,鍵盤事件,文本事件,文檔加載事件。
  表單事件包括提交表單時觸發(fā)submit事件;重置表單時觸發(fā)reset事件;表單元素內(nèi)容修改時觸發(fā)change事件;得到焦點,失去焦點時觸發(fā)focus事件,blur事件;表單元素的點擊時觸發(fā)click事件等;
  鼠標(biāo)事件包括點擊鼠標(biāo)時觸發(fā)click事件;移動鼠標(biāo)時觸發(fā)mousemove事件;按下,釋放鼠標(biāo)按鍵時觸發(fā)mousedown事件,mouseup事件;點擊右鍵時觸發(fā)contextmenu事件,可以用來修改上下文菜單;連續(xù)點擊兩次鼠標(biāo)按鍵時觸發(fā)dblclick事件;鼠標(biāo)滑到元素上,離開元素時觸發(fā)mouseover事件,mouseup事件,IE中對應(yīng)mouseenter事件,mouseleave事件;
  鍵盤事件包括按下,釋放按鍵時觸發(fā)的keydown事件,keyup事件;keydown事件與keyup事件之前會觸發(fā)keypress事件;
  文本事件,使用webkit內(nèi)核的瀏覽器支持textInput事件,該事件在產(chǎn)生可打印字符時觸發(fā);
  3.HTML5事件
  主要是指HTML5標(biāo)準(zhǔn)化的事件以及新增的事件。

事件傳播

一個事件發(fā)生時,是事件先從文檔根節(jié)點流向事件目標(biāo),然后在事件目標(biāo)上觸發(fā)事件,然后再回溯到文檔根節(jié)點,即事件傳播有三個階段,從文檔根節(jié)點流向事件目標(biāo)是捕獲階段,到達事件目標(biāo)是目標(biāo)階段,然后從事件目標(biāo)到文檔根節(jié)點是冒泡階段(IE8之前的瀏覽器不支持捕獲階段,所以其事件傳播,只有冒泡階段)。完整流程如下圖。

事件流.png

這里有一個Demo形象的模擬了事件傳播過程。

事件代理

瀏覽器都支持冒泡階段,我們可以利用瀏覽器的冒泡機制,通過監(jiān)聽父級節(jié)點來實現(xiàn)監(jiān)聽子節(jié)點的功能,這就是事件代理的概念。
  使用事件代理的好處:
    1.減少事件綁定次數(shù),提高頁面性能;
    2.可以監(jiān)聽動態(tài)變化的DOM結(jié)構(gòu),前提是父級節(jié)點不是動態(tài)變化的,子節(jié)點可以動態(tài)變化。
  原理是在父級節(jié)點綁定相應(yīng)事件處理程序,當(dāng)對應(yīng)事件在子節(jié)點觸發(fā)時通過冒泡階段把事件傳遞到父節(jié)點,在父節(jié)點觸發(fā)事件處理程序,再根據(jù)事件對象的target屬性可以獲取到是哪個事件目標(biāo),然后就可以根據(jù)不同的事件目標(biāo),來實現(xiàn)不同的業(yè)務(wù)邏輯。

事件監(jiān)聽(綁定,注冊)

主要有以下方式來注冊事件處理程序:
  1.通過設(shè)置事件目標(biāo)的事件屬性,這些事件屬性主要是由“on+事件名”組成。
  例如:
    document.getElementByTagName("a").onclick = function(){console.log("This is a click event");};
通過這種方式注冊事件處理程序,同一個事件目標(biāo)一次只能注冊一個事件處理程序。
  2.通過設(shè)置標(biāo)簽屬性注冊事件處理程序。
  例如:
    <a onclick="console.log('This is a click event')"></a>
通過這種方式只需要把函數(shù)體賦值給事件屬性即可,同樣的這種方式一次也只能注冊一個事件處理程序。
  3.支持標(biāo)準(zhǔn)事件模型的瀏覽器(IE8以及IE8之前的瀏覽器除外)中,事件目標(biāo)對象中都有一個addEventListener()方法,可以使用這個方法給事件目標(biāo)注冊事件處理程序。使用這個方法一次可以給事件目標(biāo)注冊多個不同的事件處理程序,使用不同的事件處理程序參數(shù)多次調(diào)用即可,觸發(fā)時根據(jù)注冊順序先后執(zhí)行事件處理程序。相同的事件處理程序參數(shù)多次調(diào)用這個方法注冊,也只能注冊一次。
  這個方法的完整定義:

element.addEventListener(event, function, useCapture)
event  必傳參數(shù)      指定事件名
function    必傳參數(shù)      事件處理程序
userCapture   可選參數(shù)      默認(rèn)為false,指定事件處理程序在冒泡階段執(zhí)行;ture,指定事件處理程序在捕獲階段執(zhí)行

4.不支持標(biāo)準(zhǔn)事件模型的瀏覽器(IE8以及IE8之前的瀏覽器)中,事件目標(biāo)可以使用attachEvent()方法來注冊事件處理程序。相同的事件處理程序使用這個方法可以被注冊多次。
  這個方法的完整定義:

element.attachEvent(event, function, useCapture)                   
event  必傳參數(shù)      指定 "on"+事件名
function    必傳參數(shù)      事件處理程序

由于IE8以及IE8之前瀏覽器不支持事件捕獲,所以這個方法只有兩個參數(shù)。

注意:IE9,IE10即支持addEventListener()方法又支持attachEvent()方法來注冊事件處理程序,但是IE8,IE7,IE6,IE5瀏覽器只支持attachEvent()方法注冊事件處理程序。

事件調(diào)用順序

1.通過方式1,2注冊的事件處理程序優(yōu)先執(zhí)行。
  2.通過方式3注冊的事件處理程序按照注冊順序執(zhí)行。
  3.通過方式4注冊的事件處理程序執(zhí)行順序不定,(測試發(fā)現(xiàn)IE9,IE10按照注冊順序正序執(zhí)行,IE8按照注冊順序倒序執(zhí)行)。

事件解綁,注銷

通過方式1,2注冊的事件無法解綁。
  通過方式3注冊的事件處理程序可以通過 removeEventListener()方法解綁, removeEventListener()方法有三個參數(shù),第一個參數(shù)與addEventListener()方法一樣,需要傳事件名;第二個參數(shù)需要傳 用addEventListener()方法注冊的事件處理程序函數(shù)名,即想要解綁addEventListener()方法注冊的事件處理程序,那么在注冊時必須用事先聲明好的函數(shù),不能用匿名函數(shù)注冊;第三個參數(shù)與addEventListener()方法的第三個參數(shù)一樣。
  通過方式4注冊的事件處理程序可以通過detachEvent()方法解綁,detachEvent()方法參數(shù)與attachEvent()方法參數(shù)一樣,使用時和 removeEventListener()方法類似。

事件取消

1.取消發(fā)生該事件時瀏覽器的默認(rèn)操作
    通過方式1,2注冊的事件處理程序,可以直接返回false來告訴瀏覽器不要執(zhí)行事件相關(guān)的默認(rèn)操作。
    通過方式3注冊的事件處理程序,可以直接調(diào)用事件對象的preventDefault()方法來告訴瀏覽器不要執(zhí)行事件相關(guān)的默認(rèn)操作。
    通過方式4注冊的事件處理程序,可以通過設(shè)置事件對象的returnValue屬性為false來告訴瀏覽器不要執(zhí)行事件相關(guān)的默認(rèn)操作。
  2.取消事件傳播
    通過方式1,2注冊的事件處理程序,不能取消事件傳播
    通過方式3注冊的事件處理程序,可以直接調(diào)用事件對象的stopPropagation()方法來阻止事件傳播。
    通過方式4注冊的事件處理程序,可以直接設(shè)置事件對象的cancelBubble屬性為true來阻止事件傳播。

自定義事件

對于支持標(biāo)準(zhǔn)事件模型的瀏覽器可以通過以下方式實現(xiàn)自定義事件
初始化事件類型
var event = new Event('myEvent');
或者

var event = document.createEvent('Event');
event.initEvent('myEvent',true,true);

綁定事件
element.addEventListener('myEvent',function(){});
解綁事件
element.removeEventListener('myEvent',funcName);
觸發(fā)事件
element.dispatchEvent(event);
  針對支持標(biāo)準(zhǔn)事件模型的瀏覽器處理事件時大體流程相似,主要的區(qū)別有兩點,自定義事件需要初始化事件類型,以及使用dispatchEvent方法觸發(fā)事件

IE瀏覽器注冊自定義事件可以通過IE瀏覽器的私有的事件屬性propertychange實現(xiàn),具體參考漫談js自定義事件、DOM/偽DOM自定義事件

如果引用了jquery,使用自定義事件就比較簡單了
綁定事件
element.on("myEvent",function(){});
解綁事件
element.off("myEvent");
觸發(fā)事件
element.trigger("myEvent");

自定義事件與內(nèi)置事件的區(qū)別關(guān)注點不一樣,自定義事件關(guān)注的是執(zhí)行事件的標(biāo)簽,觸發(fā)時機由程序控制;而內(nèi)置事件關(guān)注的是觸發(fā)事件的標(biāo)簽,觸發(fā)時機由瀏覽器控制。自定義事件詳細(xì)可以參考 Introducing custom events

資料來源

1.js權(quán)威指南
2.http://blog.jobbole.com/52430/
3.http://www.admin10000.com/document/6089.html
4.http://learn.jquery.com/events/introduction-to-custom-events/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,699評論 19 139
  • JavaScript 程序采用了異步事件驅(qū)動編程模型。在這種程序設(shè)計風(fēng)格下,當(dāng)文檔、瀏覽器、元素或與之相關(guān)的對象發(fā)...
    劼哥stone閱讀 1,335評論 3 11
  • 一、JS前言 (1)認(rèn)識JS 也許你已經(jīng)了解HTML標(biāo)記(也稱為結(jié)構(gòu)),知道了CSS樣式(也稱為表示),會使用HT...
    凜0_0閱讀 2,945評論 0 8
  • 第1章 認(rèn)識JS JavaScript能做什么?1.增強頁面動態(tài)效果(如:下拉菜單、圖片輪播、信息滾動等)2.實現(xiàn)...
    mo默22閱讀 1,529評論 0 5
  • 節(jié)后總是會產(chǎn)生惰性,工作不在狀態(tài),參加的活動也不在狀態(tài),錯漏百出。 自己想象中的效果與實際遇到的效果好想差了十萬八...
    諪諪_0c2f閱讀 258評論 0 0

友情鏈接更多精彩內(nèi)容