JavaScript 事件

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市弦赖,隨后出現(xiàn)的幾起案子项栏,更是在濱河造成了極大的恐慌,老刑警劉巖蹬竖,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沼沈,死亡現(xiàn)場離奇詭異,居然都是意外死亡币厕,警方通過查閱死者的電腦和手機列另,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來旦装,“玉大人页衙,你說我怎么就攤上這事∫蹙睿” “怎么了店乐?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長呻袭。 經(jīng)常有香客問我眨八,道長,這世上最難降的妖魔是什么左电? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任廉侧,我火速辦了婚禮页响,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘段誊。我一直安慰自己闰蚕,他們只是感情好,可當我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布枕扫。 她就那樣靜靜地躺著陪腌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪烟瞧。 梳的紋絲不亂的頭發(fā)上诗鸭,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天,我揣著相機與錄音参滴,去河邊找鬼强岸。 笑死,一個胖子當著我的面吹牛砾赔,可吹牛的內(nèi)容都是我干的蝌箍。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼暴心,長吁一口氣:“原來是場噩夢啊……” “哼妓盲!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起专普,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤悯衬,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后檀夹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體筋粗,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年炸渡,在試婚紗的時候發(fā)現(xiàn)自己被綠了娜亿。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡蚌堵,死狀恐怖买决,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吼畏,我是刑警寧澤督赤,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站宫仗,受9級特大地震影響够挂,放射性物質(zhì)發(fā)生泄漏旁仿。R本人自食惡果不足惜藕夫,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一孽糖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧毅贮,春花似錦办悟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至瑰煎,卻和暖如春铺然,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背酒甸。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工魄健, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人插勤。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓沽瘦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親农尖。 傳聞我的和親對象是個殘疾皇子析恋,可洞房花燭夜當晚...
    茶點故事閱讀 45,047評論 2 355