$13 事件

事件流:

事件流:頁面接收事件的順序。

IE定義的:事件冒泡流(由最具體的元素依次傳播到DOM樹的最上層的Document)

NetScape定義的:事件捕獲流(由不具體的節點依次傳播到具體的節點)

DOM事件流:先是捕獲階段,然后是處理目標階段,最后是事件冒泡階段。

事件處理程序:

a. HTML事件處理程序:

在HTML中加入事件代碼:


事件中的代碼可以在獨立的JS中,事件代碼在執行時,有權訪問全局作用域中的任何代碼。

缺點:

1.時差問題:

在JS程序還沒有具備執行條件時,就執行了事件,這時會出現錯誤。

2.耦合問題:

HTML與JS代碼緊密耦合,使得修改時需要對兩者都進行修改。

3.JS引擎不同:

不同的JS引擎對其作用域的擴展方式解析不同,在訪問非限定對象成員時會出錯。、

b.DOM0級事件處理程序:

每個元素都有自己的事件處理程序屬性。

var btn=document.getElementById("click");

btn.onclick=function () {

alert("clicked")

};

DOM0級是元素的方法,因此,事件處理程序是在元素的作用域中執行,程序中的this指向該元素。

該程序會在事件冒泡階段被處理。

如何取消:btn.onclick=null;

c.DOM2級處理程序:

定義了兩個方法:addEventListener()removeEventListener()

3個參數:事件名、事件處理程序的函數、布爾值(true事件捕獲階段處理,false事件冒泡階段處理)

btn.addEventListener("click",function () {

alert("clicked")

},false);

優點:可以對同一元素定義多個事件,事件會順序處理

btn.addEventListener("click",function () {

alert("clicked")

},false);

btn.addEventListener("click",function () {

alert(this.id);

},false);

注意:一般在事件冒泡階段處理,這樣可以最大程度兼容瀏覽器。

刪除事件:

利用addEventListener()定義的事件處理程序只能通過removeEventListener()刪除。

d. IE事件處理程序(IE Opera)

兩個方法:attachEvent()detachEvent(),兩個參數:事件類型、事件處理函數

注意:事件處理程序的作用域為全局作用域,而非元素的作用域。所以this為window。

可以定義多個事件處理程序,不過執行順序相反。

var handler=function () {

alert("clicked")

};

btn.attachEvent("onclick",handler);

btn.detachEvent("onclick",handler);

e.跨瀏覽器的事件處理程序

利用能力檢測對瀏覽器進行測試,分為三種情況:DOM2級、IE、DOM0級

主要方法:

設置一個對象EventUtil,該對象中保存兩個屬性:addHandler和removeHandler,兩個屬性對三種情況進行分類:

var EventUtil={

addHandler:function (element,type,handler) {

if(element.addEventListener){

element.addEventListener(type,handler,false);

}

elseif(element.attachEvent){

element.attachEvent("on"+type,handler);

}

else{

element["on"+type]=handler;

}

},

removeHandler:function (element,type,handler) {

if(element.removeEventListener){

element.removeEventListener(type,handler,false)

}

elseif(element.detachEvent){

element.detachEvent("on"+type,handler)

}

else{

element["on"+type]=null;

}

}

};

調用:

var btn=document.getElementById("button");

var handler=function () {

alert("clicked")

};

EventUtil.addHandler(btn,"click",handler);

EventUtil.removeHandler(btn,"click");

事件對象:event

a. DOM中的事件對象

兼容DOM的瀏覽器會將event對象傳入到事件處理程序中。無論事件處理程序使用的是DOM0還是DOM2級。

var btn=document.getElementById("btn");

btn.onclick=function (event) {

alert(event.type)

};

btn.addEventListener("click",function (event) {

alert(event.type)

},false);

在需要一個事件處理函數處理多個事件時,可以使用type類型,利用switch語句進行指定。

b. IE中的事件對象

1.訪問IE中的event方法:

DOM0:window.event

var btn=document.getElementById("btn");

btn.onclick=function () {

var event=window.event;

alert(event.type)

};

2.其他的DOM2IEHTML事件處理程序可以使用event。

c.跨瀏覽器中的事件對象

在上述的EventUtil對象中加入更多的屬性

var EventUtil={

addHandler:function (element,type,handler) {

if(element.addEventListener){

element.addEventListener(type,handler,false);

}

else if(element.attachEvent){

element.attachEvent("on"+type,handler);

}

else{

element["on"+type]=handler;

}

},

getEvent:function (event) {

return event? event:window.event;

},

getTarget:function (event) {

return event.target || event.srcElement;

},

preventDefault:function (event) {

if(event.preventDefault){

event.preventDefault();

}

else{

event.returnValue=false;

}

},

stopPropagation: function (event) {

if(event.stopPropagation){

event.stopPropagation();

}

else {

event.cancelBubble=true;

}

},

removeHandler:function (element,type,handler) {

if(element.removeEventListener){

element.removeEventListener(type,handler,false)

}

else if(element.detachEvent){

element.detachEvent("on"+type,handler)

}

else{

element["on"+type]=null;

}

}

};

使用:

先取得event,再使用其它屬性。

varbtn=document.getElementById("btn");

btn.onclick=function (event) {

varevent=EventUtil.getEvent(event);

EventUtil.getEvent(event);

};

事件類型

一:UI事件:

UI不一定與用戶操作有關。

1.load事件:

頁面完全加載完畢后觸發。也可以在圖像元素上觸發。

EventUtil.addHandler(window,"load",function (event) {

alert("加載完畢");

})

2.unload事件:

頁面被完全卸載后觸發,如頁面切換。

3.resize事件:

瀏覽器窗口被調整到一個新的高度和寬度時觸發。

EventUtil.addHandler(window,"resize",function (event) {

alert("調整高度");

})

4.scroll事件:

元素被滾動時觸發

二:焦點事件:

最主要的是focus(元素獲得焦點時觸發)和blur(元素失去焦點時觸發)

三:鼠標與滾輪事件:

9個鼠標事件:

click

mousedown

mouseup

mousemove

mouseenter

mouseleave

mouseout

mouseover

dbclick

1.客戶區坐標位置:clientX

clientY

在瀏覽器視口中的位置(不加滾輪)

在瀏覽器視口中的位置(不加滾輪)

2.頁面坐標位置: pageX pageY

在頁面中的位置(加上滾輪)

3.屏幕坐標位置:screenX screenY

相對于電腦屏幕的位置,頁面放大縮小也是相對于電腦屏幕

var

div=document.getElementsByTagName("div")[0];

EventUtil.addHandler(div,"click",function

(event) {

var

event=EventUtil.getEvent(event);

alert("CLIENTX:"+event.clientX+"screenX:"+event.screenX);

})

相關元素:

只有mouseover和mouseout才有的屬性:

relatedTarget, IE中是fromElement和toElement,

其他

事件該屬性為null

對于mouseover,相關元素是失去光標的元素,對于mouseout,相關元素是獲得光標的元

var

div=document.getElementsByTagName("div")[0];

EventUtil.addHandler(div,"mouseover",function

(event) {

var

event=EventUtil.getEvent(event);

var

target=EventUtil.getTarget(event);

var

related=EventUtil.getRelatedTarget(event);

alert("相關元素:"+event.tagName+"鼠標移入:"+related.tagName);

})

鼠標按鈕:

對mousedown和mouseup事件,在其event對象中有button屬性

DOM中button屬性有3個值:0(左鍵),1(滾輪),2(右鍵)

IE中的有8個值,0-7,這么多是沒有意義的,用戶很少同時按幾個鍵,所以需要將其轉換為

0,1,2即可。

在EventsUtil對象中加入getButton屬性

"getButton":function

(event) {

if(document.implementation.hasFeature("MouseEvents","2.0")){

return event.button;

}

else{

switch (event.button){

case 0:

case 1:

case 3:

case 5:

case 7:

return 0;

case 4:

return 1;

case 2:

case 6:

return 2;

return 2;

}

}

}

var div=document.getElementsByTagName("div")[0];

EventUtil.addHandler(div,"mousedown",function

(event) {

var event=EventUtil.getEvent(event);

var button=EventUtil.getButton(event);

alert("button屬性值:"+button);

})

鼠標滾輪事件:

mousewheel事件:其event對象中包含wheelDelta屬性,wheelDelta是120的倍數,向前是正

值,向后是負值。

特殊情況:

Opera

9.5之前的版本中,正負號顛倒。

FireFox中的該事件名稱為DOMMouseScroll,其屬性為detail,detail是3的倍數,向前是負

值,向后是正值。

四:鍵盤與文本事件:

3個鍵盤事件:

Keydown:按下任意鍵觸發

Keypress:按下字符鍵觸發,可以影響文本顯示的鍵也會觸發(如退格鍵)

keyup:釋放鍵觸發

鍵盤上的每個鍵都有對應的鍵碼,其對應的屬性為keyCode

textInput事件:DOM3中新增的替代keypress的事件。與keypress的不同:只有在可編輯區

域可以觸發textInput事件,并且只有能夠輸入實際字符的鍵才能觸發。

復合事件:

針對同時按住多個鍵輸出的字符。

變動事件:

DOM2級的變動事件處理的是DOM中的變化。比如刪除節點、插入節點時的變化。

五:HTML5事件:瀏覽器自定義的事件

contextmenu事件:上下文菜單(通過鼠標右擊實現)

點擊我看菜單

百度

必應

天貓

EventUtil.addHandler(window,"load",function

(event) {

vardiv=document.getElementById("myDiv");

EventUtil.addHandler(div,"contextmenu",function (event) {

event=EventUtil.getEvent(event);

EventUtil.preventDefault(event);

varmenu=document.getElementById("Menu");

menu.style.left=event.clientX+"px";

menu.style.top=event.clientY+"px";

menu.style.visibility="visible";

})

EventUtil.addHandler(document,"click",function (event) {

document.getElementById("Menu").style.visibility="hidden";

})

})

beforeunload事件:當用戶關閉該頁面時觸發對話框,讓用戶選擇是否離開頁面。

DOMContentLoaded事件:形成DOM樹之后即可觸發,而不用等待CSS、JS等的加載。

readystatechange事件:提供與文檔或者元素的加載狀態有關的信息。可用于加載外部JS和CSS。

pageshow和pagehide事件:在用戶使用瀏覽器的后退和前進時加快頁面的轉換速度。

haschange事件:在URL的參數列表發生變化時通知開發人員。(在AJAX應用中,開發人員經常利用URL的參數列表保存狀態)

六:設備事件:智能手機、平板電腦

orientationchange事件:屏幕的橫向與縱向

window.orientation屬性包括3個值:

0肖像模式

90向左旋轉

-90向右旋轉

MozOrientation事件:平面方向的變化。

deviceorientation事件:xyz發生變化

devicemotion事件:檢測設備是否往下掉,是否被走著的人拿在手里。

七:觸摸與手勢事件:

觸摸事件:

touchstart

touchmove

touchend

touchcancel

手勢事件:兩個手指觸摸屏幕時觸發

gesturestart

gesturechange

gestureend

內存和性能

添加大量的事件處理程序會導致頁面的整體運行性能,主要原因為:

1.大量的事件處理程序就會有大量的函數,每個函數都是一個對象,會占用大量的內存。

2.需要事先指定DOM訪問次數,延遲了頁面的交互就緒事件。

處理方法:

1.事件委托:利用了事件冒泡

原方法:


var item1=document.getElementsByTagName("li")[0];

var item2=document.getElementsByTagName("li")[1];

var item3=document.getElementsByTagName("li")[2];

EventUtil.addHandler(item1,"click",function

(event) {

location.,function

(event) {

location.,function

(event) {

location.,function

(event) {

event=EventUtil.getEvent(event);

vartarget=EventUtil.getTarget(event);

switch(target.id){

case"baidu":

location.;

break;

}

})

不是所有的事件都適合事件委托方式,適合的事件有:clickmousedown mouseupkeydown keyupkeypress

2.移除事件處理程序

當不需要事件時,需要進行事件處理程序的移除。

哪些情況不需要事件:

a.從文檔中移除了帶有事件處理程序的元素。

b.將帶有事件處理程序的元素被innerHTML刪除。

此時應該將事件設為null,btn.onclick=null;

模擬事件:利用JS來觸發而非用戶操作或者瀏覽器功能。

1.DOM中的事件模擬

a.模擬鼠標事件

b.模擬鍵盤事件

c.模擬其他事件

d.自定義DOM事件

方法:創建事件對象,初始化事件對象,觸發事件。

2.IE中的事件模擬

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,428評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,024評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,285評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,548評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,328評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,878評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,971評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,098評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,616評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,554評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,725評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,243評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,971評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,361評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,613評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,339評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,695評論 2 370

推薦閱讀更多精彩內容

  • DOM2 級事件包括: 事件捕獲,處于目標,事件冒泡 綁定事件方法: HTML上直接綁定 DOM0級事件處理程序 ...
    kopsht閱讀 399評論 0 0
  • 聲明:本文來源于http://www.webzsky.com/?p=731我只是在這里作為自己的學習筆記整理一下(...
    angryyan閱讀 7,068評論 1 6
  • 本章內容 理解事件流 使用事件處理程序 不同的事件類型 JavaScript 與 HTML 之間的交互是通過事件實...
    悶油瓶小張閱讀 285評論 0 0
  • 事件流描述從頁面中接收事件的順序 事件冒泡事件開始時由最具體的元素接收,然后逐級向上傳播到較為不具體的節點 事件捕...
    Love小六六閱讀 332評論 0 0
  • 【禪壹經略】規則? Rochina201702090201 早安吉祥! 開運之前先開心 萬事萬物皆有利於你 ???...
    派拉蒙思維俱樂部閱讀 321評論 0 0