JavaScript 事件
目標
理解什么是事件
事件流
事件類型
事件的概念
事件指可以被 JavaScript 偵測到的行為棍苹。即鼠標點擊幕侠、頁面或圖像載入油挥、鼠標懸浮于頁面的某個熱點之上顾患、在表單中選取輸入框自娩、確認表單用踩、鍵盤按鍵等操作。事件通常與函數(shù)配合使用忙迁,當事件發(fā)生時函數(shù)才會執(zhí)行脐彩。 事件名稱:click/mouseover/blur("不帶on")
響應(yīng)某個事件的函數(shù)就是事件處理程序(事件偵聽器)。 事件處理程序函數(shù)名稱:onclick/onmouseove/onblur
比如說姊扔,當用戶單擊按鈕時惠奸,就發(fā)生一個鼠標單擊(onclick)事件,需要瀏覽器做出處理恰梢,返回給用戶一個結(jié)果晨川。 事件類型:
JavaScript
事件驅(qū)動:在js中,很多地方都是通過事件觸發(fā)來驅(qū)動函數(shù)執(zhí)行删豺,從而實現(xiàn)某些功能共虑。 腳本語言:在網(wǎng)絡(luò)前端開發(fā)環(huán)境下,能夠嵌入在瀏覽器端中的一段小程序叫做腳本語言呀页。
事件流
事件發(fā)生時妈拌,會在發(fā)生事件的元素節(jié)點與DOM數(shù)根節(jié)點之間按照特定的順序進行傳播,這個過程稱為事件流 事件流指從頁面中接收事件的順序,也可理解為事件在頁面中傳播的順序。
事件發(fā)生時會在元素節(jié)點與根節(jié)點之間按照特定的順序傳播尘分,路徑所經(jīng)過的所有節(jié)點都會收到該事件猜惋,這個傳播過程即DOM事件流。
1培愁、兩種事件流模型
事件傳播的順序?qū)?yīng)瀏覽器的兩種事件流模型:捕獲型事件流和冒泡型事件流著摔。 冒泡型事件流:事件的傳播是從最特定的事件目標到最不特定的事件目標。即從DOM樹的葉子到根【推薦】 捕獲型事件流:事件的傳播是從最不特定的事件目標到最特定的事件目標定续。即從DOM樹的根到葉子谍咆。
IE的事件流是事件冒泡,而Netscape的事件流是事件捕獲私股,為了解決頁面中事件流(事件發(fā)生順序)的問題 事件冒泡的概念下在p元素上發(fā)生click事件的順序應(yīng)該是p -> div -> body -> html -> document
事件捕獲的概念下在p元素上發(fā)生click事件的順序應(yīng)該是document -> html -> body -> div -> p [
后來 w3c 采用折中的方式摹察,平息了戰(zhàn)火,制定了統(tǒng)一的標準——先捕獲再冒泡倡鲸。
一般地供嚎,將事件流分為三個階段:捕獲階段,目標階段和冒泡階段峭状。
事件綁定
方法一 HTML事件處理程序 <button onclick="fn()"></button>
-
方法二:DOM0級事件處理程序 ele.onxxx = function(){} 兼容性很好克滴,但是不允許同一個對象,多次綁定同一個事件 基本上等同于寫在行間上
<script> var btn = document.getElementById('btn'); btn.onclick = function(){ alert(1) } </script>```
方法三:DOM2級事件處理程序 obj.addEventListener(type,fn,false); IE9一下不兼容优床,允許同一個對象偿曙,多次綁定同一個事件 第一個參數(shù)是事件名(如click); 第二個參數(shù)是事件處理程序函數(shù)羔巢; 第三個參數(shù)如果是true則表示在捕獲階段調(diào)用,為false表示在冒泡階段調(diào)用
<script>
var btn = document.getElementById('btn');
btn.addEventListener('click',function(){
alert(1);
})
+ 方法四
obj.attachEvent('on'+type,fn){}
IE獨有罩阵,允許同一個對象竿秆,多次綁定同一個事件
?
btn.attachEvent('onclick',function(){
alert(1);
})
</script>```
事件處理程序分為三類:DOM0級事件處理程序、DOM2級事件處理程序稿壁、IE事件處理程序
* DOM0事件處理程序 //添加 btn.onclick = function(){} //移除 btn.onclick = null;
* DOM2事件處理程序 var handler = function(){} //添加 btn.addEventListener('click', handler,true/false); //移除 btn.removeEventListener('click', handler);
* IE 事件處理的程序 var handler = function(){} //添加 btn.attachEvent("onclick", handler); //移除 btn.removeEvent("onclick", handler);
```window.onload = function(){
?
var oBtn = document.getElementById('btn');
?
oBtn.addEventListener('click',function(){
console.log('btn處于事件捕獲階段');
}, true);
oBtn.addEventListener('click',function(){
console.log('btn處于事件冒泡階段');
}, false);
?
document.addEventListener('click',function(){
console.log('document處于事件捕獲階段');
}, true);
document.addEventListener('click',function(){
console.log('document處于事件冒泡階段');
}, false);
?
document.documentElement.addEventListener('click',function(){
console.log('html處于事件捕獲階段');
}, true);
document.documentElement.addEventListener('click',function(){
console.log('html處于事件冒泡階段');
}, false);
?
document.body.addEventListener('click',function(){
console.log('body處于事件捕獲階段');
}, true);
document.body.addEventListener('click',function(){
console.log('body處于事件冒泡階段');
}, false);
?
};```
#### 事件冒泡
冒泡:同一個事件幽钢,同一個冒泡到父元素
```<body>
<div id="content">content
<div id="btn">button</div>
</div>
?
<script type="text/javascript">
var content = document.getElementById("content");
var btn = document.getElementById('btn');
btn.onclick = function(){
alert("btn");
};
content.onclick = function(){
alert("content");
};
document.onclick = function(){
alert("document");
}
</script>
</body>
</html>```
注意:一個對象的一個事件類型只能存在一個事件模型(要么冒泡要么捕獲)
#### 如何獲取一個事件對象
DOM中,給事件處理函數(shù)一個參數(shù)e,e就是事件對象(非IE瀏覽器) 該參數(shù)不需要我們傳遞傅是,來源于系統(tǒng)傳遞,它上面有很多的屬性匪燕,每一個屬性都記載著該事件發(fā)生時的關(guān)鍵性數(shù)據(jù)。
在IE瀏覽器下可以 var event = window.event;
兼容寫法 var event = e||window.event;
事件對象上右一個專門的信息是記錄事件源的喧笔。
事件源對象: event.target 火狐只有這個 event.srcElement IE只有這個
兼容寫法: var target = event.target||event.srcElement;
#### 阻止事件冒泡
<!-- 案例帽驯;點擊文字 彈出框 點擊body彈框消失 -->
```var div = document.getElementById("div");
var a = document.getElementById("a");
a.onclick = function(e){
div.style.display = "block";
}
document.body.onclick = function(){
div.style.display = "none";
}```
方法: event.stopPropagation(); event.cancelBubble(); 兼容寫法
``` function stopPropagation(e){
if(e && e.stopPropagation){
e.stopPropagation();
}else{
window.event.cancelBubble = true;
}
}```
#### 阻止默認事件
```默認事件--a標簽跳轉(zhuǎn) 右鍵菜單
?
<a href = 'Javascript:void(0)'></a>
return false; 取消默認行為的執(zhí)行
e.preventDefault(); DOM提供的標準方法
e.returnValue = false;
```javascript
var link = document.getElementById("link");
link.onclick = function(e){
alert("hello");
}
?
// 右鍵單擊的事件叫菜單事件
document.oncontextmenu = function(ev){
?
ev.preventDefault(); //阻止默認行為
?
var div = document.createElement("div");
div.style.width = "100px";
div.style.height = "100px";
div.style.background = "green";
div.style.position = "absolute";
div.style.left = event.clientX+"px"
div.style.top = event.clientY+"px";
document.body.appendChild(div);
}
document.onclick = function(){
document.body.lastChild.remove(); //lastChild 最后一個節(jié)點
}
?
兼容寫法:
function stopDefault(e){
if(e && e.preventDefault){
e.preventDefault();
}else{
window.event.returnValue = false;
}
}
事件委托
ul.onclick = function(e){
var event = e||window.event;
var target = event.srcElement||event.target;
console.log(target);
}```
## Event對象的概念
```JavaScript與HTML的交互是通過用戶或瀏覽器操作頁面時發(fā)生的事件(Event)來處理的。
當頁面加載時书闸,它被稱為事件(Event)尼变。當用戶單擊按鈕時,單擊也是一個事件(Event)浆劲。其他示例包括按任意鍵嫌术、關(guān)閉窗口哀澈、調(diào)整窗口大小等事件(Event)。
我們可以使用這些事件(Event)來執(zhí)行JavaScript的響應(yīng)度气,比如響應(yīng)按鈕割按、向用戶顯示消息、驗證數(shù)據(jù)磷籍,等等适荣。
事件(Event)是文檔對象模型(DOM)級別3(原文:Document Object Model (DOM) Level 3)的一部分,每個HTML元素都包含一組可以觸發(fā)JavaScript代碼的事件(Event)择示。
Event對象
Event對象相關(guān)屬性
button 返回當事件被觸發(fā)時束凑,哪個鼠標按鈕被點擊。
clientX 返回當事件被觸發(fā)時栅盲,鼠標指針的水平坐標汪诉。
clientY 返回當事件被觸發(fā)時,鼠標指針的垂直坐標谈秫。
ctrlKey 返回當事件被觸發(fā)時扒寄,”CTRL” 鍵是否被按下。
metaKey 返回當事件被觸發(fā)時拟烫,”meta” 鍵是否被按下该编。
relatedTarget 返回與事件的目標節(jié)點相關(guān)的節(jié)點。
screenX 返回當某個事件被觸發(fā)時硕淑,鼠標指針的水平坐標课竣。
screenY 返回當某個事件被觸發(fā)時,鼠標指針的垂直坐標置媳。
shiftKey 返回當事件被觸發(fā)時于樟,”SHIFT” 鍵是否被按下。
cancelBubble 如果事件句柄想阻止事件傳播到包容對象拇囊,必須把該屬性設(shè)為 true迂曲。
fromElement 對于 mouseover 和 mouseout 事件,fromElement 引用移出鼠標的元素寥袭。
keyCode 對于 keypress 事件路捧,該屬性聲明了被敲擊的鍵生成的 Unicode 字符碼。對于 keydown 和 keyup
offsetX,offsetY 發(fā)生事件的地點在事件源元素的坐標系統(tǒng)中的 x 坐標和 y 坐標传黄。
returnValue 如果設(shè)置了該屬性杰扫,它的值比事件句柄的返回值優(yōu)先級高。把這個屬性設(shè)置為
srcElement 對于生成事件的 Window 對象膘掰、Document 對象或 Element 對象的引用涉波。
toElement 對于 mouseover 和 mouseout 事件,該屬性引用移入鼠標的元素。
x,y 事件發(fā)生的位置的 x 坐標和 y 坐標啤覆,它們相對于用CSS動態(tài)定位的最內(nèi)層包容元素苍日。
Event對象相關(guān)方法
srcElement/target:事件源相恃,就是發(fā)生事件的元素;
relatedTarget:返回與事件的目標節(jié)點相關(guān)的節(jié)點笨觅;
fromElement,toElement:對于 mouseover 和 mouseout 事件拦耐,fromElement 引用移出鼠標的元素,toElement引用移入鼠標的元素见剩;
currentTarget:返回其事件監(jiān)聽器觸發(fā)該事件的元素杀糯;
timeStamp:返回事件生成的日期和時間;
eventPhase:返回事件傳播的當前階段苍苞,1表示捕獲階段固翰,2表示處于目標,3表示冒泡階段羹呵;
detail:表示的是與事件相關(guān)的細節(jié)信息
bubbles:返回布爾值骂际,指示事件是否是起泡事件類型;
cancelable:返回布爾值冈欢,表示是否可以取消事件的默認行為歉铝;
cancelBubble:一個布爾屬性,默認是false凑耻。把它設(shè)置為true的時候太示,將阻止事件進一步起泡到包容層次的元素;(e.cancelBubble = true; 相當于 e.stopPropagation();)
returnValue:一個布爾屬性香浩,設(shè)置為false的時候可以阻止瀏覽器執(zhí)行默認的事件動作类缤;(e.returnValue = false; 相當于 e.preventDefault();)
defaultPrevented:表示是否調(diào)用了preventDefault()
initEvent(eventType,canBubble,cancelable):初始化新創(chuàng)建的 Event 對象的屬性;
preventDefault(): 通知瀏覽器不要執(zhí)行與事件關(guān)聯(lián)的默認動作弃衍;
stopPropagation():不再派發(fā)事件
DOM0級事件處理程序
分為2個:一是在標簽內(nèi)寫onclick事件
二是在JS寫onlick=function(){}函數(shù)
DOM2級事件處理程序
只有一個:監(jiān)聽方法,有兩個方法用來添加和移除事件處理程序:addEventListener()和removeEventListener()坚俗。
它們都有三個參數(shù):第一個參數(shù)是事件名(如click)镜盯;
第二個參數(shù)是事件處理程序函數(shù);
第三個參數(shù)如果是true則表示在捕獲階段調(diào)用猖败,為false表示在冒泡階段調(diào)用速缆。
addEventListener():可以為元素添加多個事件處理程序,觸發(fā)時會按照添加順序依次調(diào)用恩闻。 removeEventListener():不能移除匿名添加的函數(shù)艺糜。
IE事件處理程序
IE中采用的事件流是事件冒泡,先從具體的接收元素,然后逐步向上傳播到不具體的元素破停。
事件類型
UI事件
追蹤用戶在頁面中的各種行為翅楼,如監(jiān)聽表單的輸入 focus(獲得焦點) blur(失去焦點),與表單的各種交互,submit change select
焦點事件
onfocus 事件在對象獲得焦點時發(fā)生真慢。 onblur 事件會在對象失去焦點時發(fā)生毅臊。
鼠標事件
跟蹤鼠標當前定位(mouseover mouseout),跟蹤鼠標單擊(mouseup mousedown click)
click
用戶單擊鼠標主按鈕(一般為左邊按鈕)或者在獲得焦點的前提下按回車鍵時觸發(fā)。 click()方法也可以觸發(fā)click 事件黑界。
dblclick
dblclick用戶雙擊鼠標主按鈕(一般為左邊按鈕)時觸發(fā)管嬉。 mousedown:按下任意鼠標按鈕時觸發(fā)。 mouseup:釋放鼠標按鈕時觸發(fā)朗鸠。
mouseenter
鼠標光標從元素外部首次移動到元素范圍之內(nèi)時觸發(fā)蚯撩,這個事件不冒泡,而且在光標移動到后代元素上不會重復觸發(fā)烛占。通常和mouseleave搭配使用胎挎。 mousemove:鼠標光標在元素內(nèi)部移動時重復地觸發(fā)。 mouseover:鼠標光標位于一個元素外部扰楼,首次移動到另一個元素邊界之內(nèi)(包括后代元素)時觸發(fā)呀癣。
鍵盤事件
keyup keydown keypress