JavaScript 事件

JavaScript 事件

目標(biāo)

  • 理解什么是事件

  • 事件流

  • 事件類型

事件的概念

事件指可以被 JavaScript 偵測到的行為。即鼠標(biāo)點(diǎn)擊、頁面或圖像載入、鼠標(biāo)懸浮于頁面的某個(gè)熱點(diǎn)之上、在表單中選取輸入框、確認(rèn)表單、鍵盤按鍵等操作。事件通常與函數(shù)配合使用,當(dāng)事件發(fā)生時(shí)函數(shù)才會(huì)執(zhí)行。 事件名稱:click/mouseover/blur("不帶on")

響應(yīng)某個(gè)事件的函數(shù)就是事件處理程序(事件偵聽器)。 事件處理程序函數(shù)名稱:onclick/onmouseove/onblur

比如說,當(dāng)用戶單擊按鈕時(shí),就發(fā)生一個(gè)鼠標(biāo)單擊(onclick)事件,需要瀏覽器做出處理,返回給用戶一個(gè)結(jié)果。 事件類型:

JavaScript

事件驅(qū)動(dòng):在js中,很多地方都是通過事件觸發(fā)來驅(qū)動(dòng)函數(shù)執(zhí)行,從而實(shí)現(xiàn)某些功能。 腳本語言:在網(wǎng)絡(luò)前端開發(fā)環(huán)境下,能夠嵌入在瀏覽器端中的一段小程序叫做腳本語言。

事件流

事件發(fā)生時(shí),會(huì)在發(fā)生事件的元素節(jié)點(diǎn)與DOM數(shù)根節(jié)點(diǎn)之間按照特定的順序進(jìn)行傳播,這個(gè)過程稱為事件流 事件流指從頁面中接收事件的順序,也可理解為事件在頁面中傳播的順序。

事件發(fā)生時(shí)會(huì)在元素節(jié)點(diǎn)與根節(jié)點(diǎn)之間按照特定的順序傳播,路徑所經(jīng)過的所有節(jié)點(diǎn)都會(huì)收到該事件,這個(gè)傳播過程即DOM事件流。

1、兩種事件流模型

事件傳播的順序?qū)?yīng)瀏覽器的兩種事件流模型:捕獲型事件流和冒泡型事件流。 冒泡型事件流:事件的傳播是從最特定的事件目標(biāo)到最不特定的事件目標(biāo)。即從DOM樹的葉子到根【推薦】 捕獲型事件流:事件的傳播是從最不特定的事件目標(biāo)到最特定的事件目標(biāo)。即從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)一的標(biāo)準(zhǔn)——先捕獲再冒泡。


一般地,將事件流分為三個(gè)階段:捕獲階段,目標(biāo)階段和冒泡階段。

事件綁定

  • 方法一 HTML事件處理程序 <button onclick="fn()"></button>

  • 方法二:DOM0級(jí)事件處理程序 ele.onxxx = function(){} 兼容性很好,但是不允許同一個(gè)對(duì)象,多次綁定同一個(gè)事件 基本上等同于寫在行間上

    <script>
     var btn = document.getElementById('btn');
     btn.onclick = function(){
     alert(1)
     }
    </script>```
    
    
  • 方法三:DOM2級(jí)事件處理程序 obj.addEventListener(type,fn,false); IE9一下不兼容,允許同一個(gè)對(duì)象,多次綁定同一個(gè)事件 第一個(gè)參數(shù)是事件名(如click); 第二個(gè)參數(shù)是事件處理程序函數(shù); 第三個(gè)參數(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獨(dú)有,允許同一個(gè)對(duì)象,多次綁定同一個(gè)事件
?
 btn.attachEvent('onclick',function(){
 alert(1);
 })
 </script>```

事件處理程序分為三類:DOM0級(jí)事件處理程序、DOM2級(jí)事件處理程序、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);
?
 };```

#### 事件冒泡

冒泡:同一個(gè)事件,同一個(gè)冒泡到父元素

```<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>```

注意:一個(gè)對(duì)象的一個(gè)事件類型只能存在一個(gè)事件模型(要么冒泡要么捕獲)

#### 如何獲取一個(gè)事件對(duì)象

DOM中,給事件處理函數(shù)一個(gè)參數(shù)e,e就是事件對(duì)象(非IE瀏覽器)  該參數(shù)不需要我們傳遞,來源于系統(tǒng)傳遞,它上面有很多的屬性,每一個(gè)屬性都記載著該事件發(fā)生時(shí)的關(guān)鍵性數(shù)據(jù)。

在IE瀏覽器下可以 var event = window.event;

兼容寫法 var event = e||window.event;

事件對(duì)象上右一個(gè)專門的信息是記錄事件源的。

事件源對(duì)象:  event.target 火狐只有這個(gè)  event.srcElement IE只有這個(gè)

兼容寫法: var target = event.target||event.srcElement;

#### 阻止事件冒泡

<!-- 案例;點(diǎn)擊文字 彈出框 點(diǎn)擊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;
 }
 }```

#### 阻止默認(rèn)事件

```默認(rèn)事件--a標(biāo)簽跳轉(zhuǎn)  右鍵菜單
?
 <a href = 'Javascript:void(0)'></a>
 return false;        取消默認(rèn)行為的執(zhí)行
 e.preventDefault();  DOM提供的標(biāo)準(zhǔn)方法
 e.returnValue = false;
```javascript
var link = document.getElementById("link");
link.onclick = function(e){
 alert("hello");
}

?

// 右鍵單擊的事件叫菜單事件
 document.oncontextmenu = function(ev){
?
 ev.preventDefault();  //阻止默認(rèn)行為
?
 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 最后一個(gè)節(jié)點(diǎn)
 }
?

兼容寫法:

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對(duì)象的概念

```JavaScript與HTML的交互是通過用戶或?yàn)g覽器操作頁面時(shí)發(fā)生的事件(Event)來處理的。
當(dāng)頁面加載時(shí),它被稱為事件(Event)。當(dāng)用戶單擊按鈕時(shí),單擊也是一個(gè)事件(Event)。其他示例包括按任意鍵、關(guān)閉窗口、調(diào)整窗口大小等事件(Event)。
我們可以使用這些事件(Event)來執(zhí)行JavaScript的響應(yīng),比如響應(yīng)按鈕、向用戶顯示消息、驗(yàn)證數(shù)據(jù),等等。
事件(Event)是文檔對(duì)象模型(DOM)級(jí)別3(原文:Document Object Model (DOM) Level 3)的一部分,每個(gè)HTML元素都包含一組可以觸發(fā)JavaScript代碼的事件(Event)。

Event對(duì)象

Event對(duì)象相關(guān)屬性

button  返回當(dāng)事件被觸發(fā)時(shí),哪個(gè)鼠標(biāo)按鈕被點(diǎn)擊。
clientX 返回當(dāng)事件被觸發(fā)時(shí),鼠標(biāo)指針的水平坐標(biāo)。
clientY 返回當(dāng)事件被觸發(fā)時(shí),鼠標(biāo)指針的垂直坐標(biāo)。
ctrlKey 返回當(dāng)事件被觸發(fā)時(shí),”CTRL” 鍵是否被按下。
metaKey 返回當(dāng)事件被觸發(fā)時(shí),”meta” 鍵是否被按下。
relatedTarget   返回與事件的目標(biāo)節(jié)點(diǎn)相關(guān)的節(jié)點(diǎn)。
screenX 返回當(dāng)某個(gè)事件被觸發(fā)時(shí),鼠標(biāo)指針的水平坐標(biāo)。
screenY 返回當(dāng)某個(gè)事件被觸發(fā)時(shí),鼠標(biāo)指針的垂直坐標(biāo)。
shiftKey    返回當(dāng)事件被觸發(fā)時(shí),”SHIFT” 鍵是否被按下。

cancelBubble    如果事件句柄想阻止事件傳播到包容對(duì)象,必須把該屬性設(shè)為 true。
fromElement 對(duì)于 mouseover 和 mouseout 事件,fromElement 引用移出鼠標(biāo)的元素。
keyCode 對(duì)于 keypress 事件,該屬性聲明了被敲擊的鍵生成的 Unicode 字符碼。對(duì)于 keydown 和 keyup
offsetX,offsetY 發(fā)生事件的地點(diǎn)在事件源元素的坐標(biāo)系統(tǒng)中的 x 坐標(biāo)和 y 坐標(biāo)。
returnValue 如果設(shè)置了該屬性,它的值比事件句柄的返回值優(yōu)先級(jí)高。把這個(gè)屬性設(shè)置為
srcElement  對(duì)于生成事件的 Window 對(duì)象、Document 對(duì)象或 Element 對(duì)象的引用。
toElement   對(duì)于 mouseover 和 mouseout 事件,該屬性引用移入鼠標(biāo)的元素。
x,y 事件發(fā)生的位置的 x 坐標(biāo)和 y 坐標(biāo),它們相對(duì)于用CSS動(dòng)態(tài)定位的最內(nèi)層包容元素。

Event對(duì)象相關(guān)方法

srcElement/target:事件源,就是發(fā)生事件的元素;
relatedTarget:返回與事件的目標(biāo)節(jié)點(diǎn)相關(guān)的節(jié)點(diǎn);
fromElement,toElement:對(duì)于 mouseover 和 mouseout 事件,fromElement 引用移出鼠標(biāo)的元素,toElement引用移入鼠標(biāo)的元素;
currentTarget:返回其事件監(jiān)聽器觸發(fā)該事件的元素;
timeStamp:返回事件生成的日期和時(shí)間;
eventPhase:返回事件傳播的當(dāng)前階段,1表示捕獲階段,2表示處于目標(biāo),3表示冒泡階段;
detail:表示的是與事件相關(guān)的細(xì)節(jié)信息
bubbles:返回布爾值,指示事件是否是起泡事件類型;
cancelable:返回布爾值,表示是否可以取消事件的默認(rèn)行為;
cancelBubble:一個(gè)布爾屬性,默認(rèn)是false。把它設(shè)置為true的時(shí)候,將阻止事件進(jìn)一步起泡到包容層次的元素;(e.cancelBubble = true; 相當(dāng)于 e.stopPropagation();)
returnValue:一個(gè)布爾屬性,設(shè)置為false的時(shí)候可以阻止瀏覽器執(zhí)行默認(rèn)的事件動(dòng)作;(e.returnValue = false; 相當(dāng)于 e.preventDefault();)
defaultPrevented:表示是否調(diào)用了preventDefault()
initEvent(eventType,canBubble,cancelable):初始化新創(chuàng)建的 Event 對(duì)象的屬性;
preventDefault(): 通知瀏覽器不要執(zhí)行與事件關(guān)聯(lián)的默認(rèn)動(dòng)作;
stopPropagation():不再派發(fā)事件

DOM0級(jí)事件處理程序

分為2個(gè):一是在標(biāo)簽內(nèi)寫onclick事件

二是在JS寫onlick=function(){}函數(shù)

DOM2級(jí)事件處理程序

只有一個(gè):監(jiān)聽方法,有兩個(gè)方法用來添加和移除事件處理程序:addEventListener()和removeEventListener()。

它們都有三個(gè)參數(shù):第一個(gè)參數(shù)是事件名(如click);

第二個(gè)參數(shù)是事件處理程序函數(shù);

第三個(gè)參數(shù)如果是true則表示在捕獲階段調(diào)用,為false表示在冒泡階段調(diào)用。

addEventListener():可以為元素添加多個(gè)事件處理程序,觸發(fā)時(shí)會(huì)按照添加順序依次調(diào)用。 removeEventListener():不能移除匿名添加的函數(shù)。

IE事件處理程序

IE中采用的事件流是事件冒泡,先從具體的接收元素,然后逐步向上傳播到不具體的元素。

事件類型

UI事件

追蹤用戶在頁面中的各種行為,如監(jiān)聽表單的輸入 focus(獲得焦點(diǎn)) blur(失去焦點(diǎn)),與表單的各種交互,submit change select

焦點(diǎn)事件

onfocus 事件在對(duì)象獲得焦點(diǎn)時(shí)發(fā)生。 onblur 事件會(huì)在對(duì)象失去焦點(diǎn)時(shí)發(fā)生。

鼠標(biāo)事件

跟蹤鼠標(biāo)當(dāng)前定位(mouseover mouseout),跟蹤鼠標(biāo)單擊(mouseup mousedown click)

click

用戶單擊鼠標(biāo)主按鈕(一般為左邊按鈕)或者在獲得焦點(diǎn)的前提下按回車鍵時(shí)觸發(fā)。 click()方法也可以觸發(fā)click 事件。

dblclick

dblclick用戶雙擊鼠標(biāo)主按鈕(一般為左邊按鈕)時(shí)觸發(fā)。 mousedown:按下任意鼠標(biāo)按鈕時(shí)觸發(fā)。 mouseup:釋放鼠標(biāo)按鈕時(shí)觸發(fā)。

mouseenter

鼠標(biāo)光標(biāo)從元素外部首次移動(dòng)到元素范圍之內(nèi)時(shí)觸發(fā),這個(gè)事件不冒泡,而且在光標(biāo)移動(dòng)到后代元素上不會(huì)重復(fù)觸發(fā)。通常和mouseleave搭配使用。 mousemove:鼠標(biāo)光標(biāo)在元素內(nèi)部移動(dòng)時(shí)重復(fù)地觸發(fā)。 mouseover:鼠標(biāo)光標(biāo)位于一個(gè)元素外部,首次移動(dòng)到另一個(gè)元素邊界之內(nèi)(包括后代元素)時(shí)觸發(fā)。

鍵盤事件

keyup keydown keypress

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

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