JavaScript每天必學(xué)之事件
其實(shí)這篇文章挺早之前就寫(xiě)了,但是由于sf保存方面的bug,所以當(dāng)時(shí)寫(xiě)了一大堆,結(jié)果沒(méi)保存,覺(jué)得這個(gè)沒(méi)寫(xiě)完是個(gè)不小的遺憾,今天正好有空,就給補(bǔ)充下了,也正好給我的javascript學(xué)習(xí)總結(jié)做一個(gè)完結(jié)篇。
這里,主要討論一下js相關(guān)的事件——
事件處理程序
在DOM中定義了一些事件, 而響應(yīng)某個(gè)事件的函數(shù)就叫事件處理程序(或事件偵聽(tīng)器)。事件處理程序的名字一般以“on”開(kāi)頭,例如:onclick等
事件冒泡與捕獲
事件流指的是頁(yè)面中接收事件的順序,IE,火狐和chrome瀏覽器都是事件冒泡,所謂是事件冒泡指的是事件最開(kāi)始由最具體的元素接收,然后逐級(jí)向上傳播到不具體的節(jié)點(diǎn)。而事件捕獲則正好相反,事件捕獲是由Netscape提出的,事件冒泡和捕獲具體如下圖所示:
雖然事件捕獲是Netscape唯一支持的事件流模型,但目前IE9,火狐和谷歌也都支持這種事件流模型。
事件冒泡的好處
因?yàn)槭录哂忻芭輽C(jī)制,因此我們可以利用冒泡的原理,把事件加到父級(jí)上,觸發(fā)執(zhí)行效果。這樣做的好處當(dāng)然就是提高性能了,
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
window.onload = function () {
var aUl = document.getElementsById("bubble");
var aLi = aUl.getElementsByTagName("li");
for(var i = 0;i<aLi.length;i++){
aLi[i].onmouseover = function () {
this.style.backgroundColor = "blue";
};
ali[i].onmouseout = function () {
this.style.backgroundColor = "";
}
}
};
</script>
</head>
<body>
<div>
<ul id = "bubble">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
</body>
這樣我們就可以做到li上面添加鼠標(biāo)事件。但是如果說(shuō)我們可能有很多個(gè)li用for循環(huán)的話(huà)就比較影響性能。
下面我們可以用事件委托的方式來(lái)實(shí)現(xiàn)這樣的效果。html不變:
<script type="text/javascript">
window.onload = function () {
var aUl = document.getElementsById("bubble");
var aLi = aUl.getElementsByTagName("li");
//不管在哪個(gè)事件中,只要你操作的那個(gè)元素就是事件源。
// ie:window.event.srcElement
// 標(biāo)準(zhǔn)下:event.target
aUl.onmouseover = function (ev) {
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == "li"){
target.style.background = "blue";
}
};
aUl.onmouseout = function (ev) {
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() = "li"){
target.style.background = "";
}
}
};
</script>
那么,如何阻止事件的冒泡呢,看下面一個(gè)例子:
<div onclick="showMsg(this,event)" id="outSide" style="width:100px; height:100px; background:#000; padding:50px">
<div onclick="showMsg(this,event)" id="inSide" style="width:100px; height:100px; background:#CCC"></div>
</div>
<script type="text/javascript">
//阻止事件冒泡后,你點(diǎn)擊灰色盒子,整個(gè)過(guò)程只彈一次對(duì)話(huà)框了(注意與默認(rèn)情況對(duì)比)
function showMsg(obj,e)
{
alert(obj.id);
stopBubble(e)
}
//阻止事件冒泡函數(shù)
function stopBubble(e)
{
if (e && e.stopPropagation)
e.stopPropagation()
else
window.event.cancelBubble=true
}
</script>
點(diǎn)擊黑色外圍的效果圖:

DOM 0級(jí)事件處理程序
通過(guò)js指定事件處理程序通常是將回調(diào)函數(shù)賦給這個(gè)事件處理程序的屬性。每個(gè)元素都有自己的事件處理程序?qū)傩裕▽傩孕?xiě),例如:onclick)
btn.onclick = function(){
console.log('hello');
};
使用DOM 0級(jí)指定的事件處理程序被認(rèn)為是元素的方法。因此,this指向當(dāng)前元素:
var btn = document.getElementById('myDiv');
//DOM上觸發(fā)的事件會(huì)產(chǎn)生一個(gè)事件對(duì)象event
btn.onclick = function (event) {
alert(this.id);//myDiv
};
DOM level 1
DOM level 1 專(zhuān)注于 HTML 和 XML 文檔模型。它含有文檔導(dǎo)航和處理功能。
DOM level 1 于 1998 年 10 月 1 日成為 W3C 推薦標(biāo)準(zhǔn)。
第二版的工作草案在 2000 年 9 月 29 日。
值得一提的是:DOM level 0 并不是 W3C 規(guī)范。而僅僅是對(duì)在 Netscape Navigator 3.0 和 IE 3.0 中的等價(jià)功能性的一種定義。
DOM 2級(jí)事件處理程序
DOM 2級(jí)定義了兩個(gè)方法,用于指定和刪除事件處理程序的操作:addEventListener()和removeEventListener(),他們都接受三個(gè)參數(shù):
1.事件名。比如上面的click
2.作為事件處理程序的函數(shù)。
3.布爾值(true表示捕獲階段調(diào)用事件處理程序,false表示冒泡階段)
通過(guò)Element對(duì)象的addEventListener方法,也可以定義事件的回調(diào)函數(shù)。
//element.addEventListener(event, function, useCapture)
var btn = document.getElementById('myDiv');
btn.addEventListener('click', function () {
console.log(this.id);
},false);
IE中的事件處理程序
IE9之前的IE瀏覽器不支持addEventListener()和removeEventListener()。
與其他瀏覽器不同的是,IE使用的是attachEvent()和detachEvent()方法來(lái)為DOM添加事件處理程序,由于IE8及更早版本只支持事件冒泡,所以他們只接受兩個(gè)參數(shù):
1、事件處理程序名稱(chēng)(前面要加on)
2、事件處理程序函數(shù)
使用attachEvent()添加的事件處理程序如下:
var btn = document.getElementById('myDiv');
btn.attachEvent('onclick', function () {
console.log(this.id);
});
值得注意的是,使用attachEvent()方法的情況下,事件處理程序會(huì)在全局作用域中運(yùn)行,所以,此時(shí)this等于window
事件對(duì)象
在觸發(fā)DOM上的某個(gè)事件時(shí),會(huì)產(chǎn)生一個(gè)事件對(duì)象event,這個(gè)對(duì)象包含著所有與事件相關(guān)的信息。包括導(dǎo)致事件的元素、事件的類(lèi)型以及其他與特定事件相關(guān)的信息。event對(duì)象會(huì)被作為第一個(gè)參數(shù)傳遞給事件監(jiān)聽(tīng)的回調(diào)函數(shù)。我們可以通過(guò)這個(gè)event對(duì)象來(lái)獲取到大量當(dāng)前事件相關(guān)的信息:
type (String) — 事件的名稱(chēng)
target (node) — 事件起源的DOM節(jié)點(diǎn)
currentTarget?(node) — 當(dāng)前回調(diào)函數(shù)被觸發(fā)的DOM節(jié)點(diǎn)(后面會(huì)做比較詳細(xì)的介紹)
bubbles (boolean) — 指明這個(gè)事件是否是一個(gè)冒泡事件(接下來(lái)會(huì)做解釋?zhuān)?br />
preventDefault(function) — 這個(gè)方法將阻止瀏覽器中用戶(hù)代理對(duì)當(dāng)前事件的相關(guān)默認(rèn)行為被觸發(fā)。比如阻止<a>元素的click事件加載一個(gè)新的頁(yè)面
cancelable (boolean) — 這個(gè)變量指明這個(gè)事件的默認(rèn)行為是否可以通過(guò)調(diào)用event.preventDefault來(lái)阻止。
stopPropagation (function) — 取消事件的進(jìn)一步捕獲或冒泡,bubbles為true使用這個(gè)方法
eventPhase:返回一個(gè)數(shù)字,表示事件目前所處的階段,0為事件開(kāi)始從DOM表層向目標(biāo)元素傳播,1為捕獲階段,2為事件到達(dá)目標(biāo)元素,3為冒泡階段。
此外,事件對(duì)象還可能擁有很多其他的屬性,但是他們都是針對(duì)特定的event的。比如,鼠標(biāo)事件包含clientX和clientY屬性來(lái)表明鼠標(biāo)在當(dāng)前視窗的位置。
另外,stopPropagation()方法用于立即停止事件在DOM中的傳播,即取消進(jìn)一步的事件冒泡或捕獲。
var btn = document.getElementById('myDiv');
btn.onclick = function (event) {
alert("clicked");
event.stopPropagation();
};
//避免觸發(fā)在document.body上的事件處理程序
document.body.onclick = function (event) {
alert("Body clicked");
};
只有在事件處理程序執(zhí)行期間,event對(duì)象才會(huì)存在,一旦事件處理程序執(zhí)行完畢,event對(duì)象就會(huì)自動(dòng)銷(xiāo)毀。
IE中的事件對(duì)象
在DOM 0級(jí)中添加事件處理程序時(shí),event對(duì)象是作為window對(duì)象的一個(gè)屬性存在的:
var btn = document.getElementById('myDiv');
btn.onclick = function (event) {
var event = window.event;
alert(event.type);//click
};
IE 的event對(duì)象同樣也包含與創(chuàng)建它的事件相關(guān)的屬性和方法。
cancleBubble 布爾 默認(rèn)值時(shí)false,但可以被設(shè)置成true來(lái)取消事件冒泡,與dom中的 stopPropagation()方法相同。
returnValue 布爾 默認(rèn)值是true,當(dāng)設(shè)置成false時(shí)用以取消事件的默認(rèn)行為 與dom中的preventDefault()相同。
srcElement 元素 事件的目標(biāo),與dom中的target屬性相同。
type 字符串 被觸發(fā)的事件類(lèi)型。
click事件
當(dāng)用戶(hù)點(diǎn)擊以后,event對(duì)象會(huì)包含以下屬性。
pageX,pageY:點(diǎn)擊位置相對(duì)于html元素的坐標(biāo),單位為像素。
clientX,clientY:點(diǎn)擊位置相對(duì)于視口(viewport)的坐標(biāo),單位為像素。
screenX,screenY:點(diǎn)擊位置相對(duì)于設(shè)備顯示屏幕的坐標(biāo),單位為設(shè)備硬件的像素
clientX,clientY
圖示:clientX和clientY,他們的值表示事件發(fā)生時(shí)鼠標(biāo)指針在視口中的水平和垂直坐標(biāo)(不包含滾動(dòng)條區(qū)域)

偏移量
通過(guò)以下4個(gè)屬性可以取得元素的偏移量。
(1)offsetHeight:元素在垂直方向上占用的空間大小,以像素計(jì)。包括元素的高度、(可見(jiàn)的)水平滾動(dòng)條的高度、上邊框高度和下邊框高度。
(2)offsetWidth:元素在水平方向上占用的空間大小,以像素計(jì)。包括元素的寬度、(可見(jiàn)的)垂直滾動(dòng)條的寬度、左邊框?qū)挾群陀疫吙驅(qū)挾取?/p>
(3)offsetLeft:元素的左外邊框至包含元素的左內(nèi)邊框之間的像素距離。
(4)offsetTop:元素的上外邊框至包含元素的上內(nèi)邊框之間的像素距離。
pageX,pageY
這兩個(gè)屬性表示鼠標(biāo)光標(biāo)在頁(yè)面中的位置,在頁(yè)面沒(méi)有滾動(dòng)的情況下,pageX,pageY的值與clientX,clientY的值相等
滾動(dòng)大小
滾動(dòng)大小,指的是包含滾動(dòng)內(nèi)容的元素的大小。
以下是4個(gè)與滾動(dòng)大小相關(guān)的屬性。
(1)scrollHeight:在沒(méi)有滾動(dòng)條的情況下,元素內(nèi)容的總高度。
(2)scrollWidth:在沒(méi)有滾動(dòng)條的情況下,元素內(nèi)容的總寬度。
(3)scrollLeft:被隱藏在內(nèi)容區(qū)域左側(cè)的像素?cái)?shù)。通過(guò)設(shè)置這個(gè)屬性可以改變?cè)氐臐L動(dòng)位置。
(4)scrollTop:被隱藏在內(nèi)容區(qū)域上方的像素?cái)?shù)。通過(guò)設(shè)置這個(gè)屬性可以改變?cè)氐臐L動(dòng)位置。
焦點(diǎn)事件
焦點(diǎn)事件會(huì)在頁(yè)面元素獲得或失去焦點(diǎn)時(shí)觸發(fā),有以下4個(gè)焦點(diǎn)事件:
1.blur:元素失去焦點(diǎn)時(shí)觸發(fā),該事件不冒泡
2.focus:元素獲得焦點(diǎn)時(shí)觸發(fā)。不冒泡
3.focusin:元素獲得焦點(diǎn)時(shí)觸發(fā),冒泡
4.focusout:元素失去焦點(diǎn)時(shí)觸發(fā),冒泡
鼠標(biāo)事件
DOM 3級(jí)定義了9個(gè)鼠標(biāo)事件:
click:當(dāng)用戶(hù)點(diǎn)擊鼠標(biāo)主鍵通常是指鼠標(biāo)左鍵或按回車(chē)鍵時(shí)觸發(fā)。
dbclick:用戶(hù)雙擊鼠標(biāo)時(shí)觸發(fā)
mousedown:當(dāng)用戶(hù)按下鼠標(biāo)任意一個(gè)鍵都會(huì)觸發(fā),這個(gè)事件是不能夠通過(guò)鍵盤(pán)觸發(fā)的。
mousemove:當(dāng)鼠標(biāo)在某元素周?chē)苿?dòng)時(shí)重復(fù)觸發(fā),該事件不能通過(guò)鍵盤(pán)事件觸發(fā)。
mouseout:當(dāng)鼠標(biāo)離開(kāi)元素時(shí)觸發(fā),這個(gè)事件不能通過(guò)鍵盤(pán)觸發(fā)。
mouseover:當(dāng)鼠標(biāo)進(jìn)入元素時(shí)觸發(fā),這個(gè)事件不能夠通過(guò)鍵盤(pán)觸發(fā)。
mouseenter:類(lèi)似“mouseover”,但不冒泡,而且當(dāng)光標(biāo)移到后代元素上不會(huì)觸發(fā)。
mouseleave:類(lèi)似“mouseout”,但不冒泡。在元素上方是不觸發(fā)。
mouseup:當(dāng)用戶(hù)釋放鼠標(biāo)按鍵時(shí)觸發(fā),不能夠通過(guò)鍵盤(pán)觸發(fā)。
傳遞給鼠標(biāo)事件處理程序的事件對(duì)象有clientX和clientY屬性,它們指定了鼠標(biāo)指針相對(duì)于包含窗口的坐標(biāo)。加入窗口的滾動(dòng)偏移量,就可以把鼠標(biāo)位置轉(zhuǎn)換成文檔坐標(biāo)。
頁(yè)面上的所有元素都支持鼠標(biāo)事件。除了mouseenter和mouseleave外,所有的事件都冒泡,并且他們的默認(rèn)行為是可以被取消掉的。但取消鼠標(biāo)事件的默認(rèn)行為可能會(huì)影響到其他事件,因?yàn)橛行┦髽?biāo)事件是相互依賴(lài)的。
拖拉事件
(1)drag事件
drag事件在源對(duì)象被拖拉過(guò)程中觸發(fā)。
(2)dragstart,dragend事件
dragstart事件在用戶(hù)開(kāi)始用鼠標(biāo)拖拉某個(gè)對(duì)象時(shí)觸發(fā),dragend事件在結(jié)束拖拉時(shí)觸發(fā)。
(3)dragenter,dragleave事件
dragenter事件在源對(duì)象拖拉進(jìn)目標(biāo)對(duì)象后,在目標(biāo)對(duì)象上觸發(fā)。dragleave事件在源對(duì)象離開(kāi)目標(biāo)對(duì)象后,在目標(biāo)對(duì)象上觸發(fā)。
(4)dragover事件
dragover事件在源對(duì)象拖拉過(guò)另一個(gè)對(duì)象上方時(shí),在后者上觸發(fā)。
(5)drop事件
當(dāng)源對(duì)象被拖拉到目標(biāo)對(duì)象上方,用戶(hù)松開(kāi)鼠標(biāo)時(shí),在目標(biāo)對(duì)象上觸發(fā)drop事件。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
javascript事件處理模型實(shí)例說(shuō)明
本文主要介紹IE和火狐在添加刪除事件上的區(qū)別,并給出通用的解決方法,需要的朋友可以參考下。2016-05-05
JS如何實(shí)現(xiàn)form表單登錄驗(yàn)證并使用MD5加密詳解
表單驗(yàn)證為終端用戶(hù)檢測(cè)無(wú)效的數(shù)據(jù)并標(biāo)記這些錯(cuò)誤,是一種用戶(hù)體驗(yàn)的優(yōu)化,下面這篇文章主要給大家介紹了關(guān)于JS如何實(shí)現(xiàn)form表單登錄驗(yàn)證并使用MD5加密的相關(guān)資料,需要的朋友可以參考下2023-06-06
JavaScript獲取和設(shè)置CheckBox狀態(tài)的簡(jiǎn)單方法
這篇文章介紹了JavaScript獲取和設(shè)置CheckBox狀態(tài)的簡(jiǎn)單方法,有需要的朋友可以參考一下2013-07-07
神奇!js+CSS+DIV實(shí)現(xiàn)文字顏色漸變效果
很神奇!js+CSS+DIV實(shí)現(xiàn)文字顏色漸變效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-03-03
微信小程序使用自定義組件導(dǎo)航實(shí)現(xiàn)當(dāng)前頁(yè)面高亮
這篇文章主要介紹了微信小程序使用自定義組件導(dǎo)航實(shí)現(xiàn)當(dāng)前頁(yè)面高亮,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01
JS拖動(dòng)技術(shù) 關(guān)于setCapture使用
JS拖動(dòng)技術(shù) 關(guān)于setCapture使用,學(xué)習(xí)js拖動(dòng)效果的朋友可以參考下。2010-12-12
微信小程序登錄態(tài)和檢驗(yàn)注冊(cè)過(guò)沒(méi)的app.js寫(xiě)法
這篇文章主要介紹了小程序登錄態(tài)和檢驗(yàn)注冊(cè)過(guò)沒(méi)的app.js寫(xiě)法, 本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的借鑒價(jià)值,需要的朋友可以參考下2019-05-05
在多個(gè)頁(yè)面使用同一個(gè)HTML片段的代碼
有一個(gè)比較復(fù)雜的HTML片段(A),如果把這個(gè)HTML片段嵌入到其他頁(yè)面中(B,C,D....)。 問(wèn)題的關(guān)鍵是在HTML片段中有大量的JavaScript邏輯需要處理,比如說(shuō)分頁(yè),點(diǎn)擊事件響應(yīng)等。2011-03-03
JS為什么說(shuō)async/await是generator的語(yǔ)法糖詳解
這篇文章主要給大家介紹了關(guān)于JS為什么說(shuō)async/await是generator的語(yǔ)法糖的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用JS具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07

