JavaScript的事件機制

在JavaScript的學習中徘意,我們經(jīng)常會遇到JavaScript的事件機制,例如净嘀,事件綁定报咳、事件監(jiān)聽、事件委托(事件代理)等挖藏。

一暑刃、事件綁定

要想讓 JavaScript 對用戶的操作作出響應(yīng),首先要對 DOM 元素綁定事件處理函數(shù)熬苍。所謂事件處理函數(shù)稍走,就是處理用戶操作的函數(shù),不同的操作對應(yīng)不同的名稱柴底。

在JavaScript中婿脸,有三種常用的綁定事件的方法:

  • DOM元素直接綁定
  • JavaScript代碼綁定
  • 綁定事件監(jiān)聽函數(shù)
1、DOM直接綁定事件

我們可以在DOM元素上綁定onclick柄驻、onmouseover狐树、onmouseout、onmousedown鸿脓、onmouseup抑钟、ondblclick、onkeydown野哭、onkeypress在塔、onkeyup等。

<input type="button" value="click me" onclick="hello()">
<script>
function hello(){
 alert("hello world!");
}
</script>
2拨黔、JavaScript代碼綁定事件

在JavaScript代碼中綁定事件可以使JavaScript代碼與HTML標簽分離蛔溃,文檔結(jié)構(gòu)清晰,便于管理和開發(fā)。

<input type="button" value="click me" id="btn">
<script>
document.getElementById("btn").onclick = function(){
 alert("hello world!");
}
</script>
3贺待、使用事件監(jiān)聽綁定事件

綁定事件的另一種方法是用 addEventListener() 或 attachEvent() 來綁定事件監(jiān)聽函數(shù)徽曲。下面進行詳細介紹。

二麸塞、事件監(jiān)聽

關(guān)于事件監(jiān)聽秃臣,W3C規(guī)范中定義了3個事件階段,依次是捕獲階段哪工、目標階段奥此、冒泡階段。起初Netscape制定了JavaScript的一套事件驅(qū)動機制(即事件捕獲)正勒。隨即IE也推出了自己的一套事件驅(qū)動機制(即事件冒泡)得院。最后W3C規(guī)范了兩種事件機制,分為捕獲階段章贞、目標階段祥绞、冒泡階段。IE8以前IE一直堅持自己的事件機制鸭限,IE9以后IE也支持了W3C規(guī)范蜕径。

1、W3C規(guī)范

語法:

element.addEventListener(event, function, useCapture)
  • event : (必需)事件名败京,支持所有 DOM事件 兜喻。
  • function:(必需)指定要事件觸發(fā)時執(zhí)行的函數(shù)。
  • useCapture:(可選)指定事件是否在捕獲或冒泡階段執(zhí)行赡麦。true朴皆,捕獲。false泛粹,冒泡遂铡。默認false。
  • 注:IE8以下不支持晶姊。
<input type="button" value="click me" id="btn1">
<script>
document.getElementById("btn1").addEventListener("click",hello);
function hello(){
 alert("hello world!");
}
</script>
2扒接、IE標準

語法:

element.attachEvent(event, function)
  • event:(必需)事件類型。需加“on“们衙,例如:onclick钾怔。
  • function:(必需)指定要事件觸發(fā)時執(zhí)行的函數(shù)。
<input type="button" value="click me" id="btn2">
<script>
document.getElementById("btn2").attachEvent("onclick",hello);
function hello(){
 alert("hello world!");
}
</script>

3蒙挑、事件監(jiān)聽的優(yōu)點

3.1宗侦、常規(guī)的事件綁定只執(zhí)行最后綁定的事件。

<input type="button" value="click me" id="btn3">
<script>
var btn3 = document.getElementById("btn3");
btn3.onclick = function(){
 alert("hello 1"); //不執(zhí)行
}
btn3.onclick = function(){
 alert("hello 2"); //執(zhí)行
}
</script>

采用事件監(jiān)聽機制可以綁定多個事件忆蚀。

<input type="button" value="click me" id="btn4">
<script>
var btn4 = document.getElementById("btn4");
btn4.addEventListener("click",hello1);
btn4.addEventListener("click",hello2);
function hello1(){
 alert("hello 1");   //執(zhí)行
}
function hello2(){
 alert("hello 2");   //執(zhí)行
}
</script>

3.2矾利、可以解除相應(yīng)的綁定

<input type="button" value="click me" id="btn5">
<script>
var btn5 = document.getElementById("btn5");
btn5.addEventListener("click",hello1);//執(zhí)行了
btn5.addEventListener("click",hello2);//不執(zhí)行
btn5.removeEventListener("click",hello2);
function hello1(){
 alert("hello 1");
}
function hello2(){
 alert("hello 2");
}
</script>

3.3懊悯、封裝事件監(jiān)聽

<input type="button" value="click me" id="btn5">
//綁定監(jiān)聽事件
function addEventHandler(target,type,fn){
 if(target.addEventListener){
 target.addEventListener(type,fn);
 }else{
 target.attachEvent("on"+type,fn);
 }
}
//移除監(jiān)聽事件
function removeEventHandler(target,type,fn){
 if(target.removeEventListener){
 target.removeEventListener(type,fn);
 }else{
 target.detachEvent("on"+type,fn);
 }
}
//測試
var btn5 = document.getElementById("btn5");
addEventHandler(btn5,"click",hello1);//添加事件hello1
addEventHandler(btn5,"click",hello2);//添加事件hello2
removeEventHandler(btn5,"click",hello1);//移除事件hello1

三、事件委托

事件委托就是利用冒泡的原理梦皮,把事件加到父元素或祖先元素上,觸發(fā)執(zhí)行效果桃焕。

    <input type="button" value="click me" id="btn6">
    var btn6 = document.getElementById("btn6");
    document.onclick = function(event){
     event = event || window.event;
     var target = event.target || event.srcElement;
     if(target == btn6){
     alert(btn5.value);
     }
    }

上面只是個例子剑肯,代碼盡可能的簡化了。在實際的代碼中 我們可能用到j(luò)Query的live()观堂、delegate()让网、bind()、on()等师痕。

事件委托優(yōu)點

提高JavaScript性能溃睹。事件委托可以顯著的提高事件的處理速度,減少內(nèi)存的占用胰坟。 實例分析JavaScript中的事件委托和事件綁定 因篇。

傳統(tǒng)寫法
<ul id="list">
 <li id="item1" >item1</li>
 <li id="item2" >item2</li>
 <li id="item3" >item3</li>
</ul>
<script>
var item1 = document.getElementById("item1");
var item2 = document.getElementById("item2");
var item3 = document.getElementById("item3");
 
item1.onclick = function(){
 alert("hello item1");
}
item2.onclick = function(){
 alert("hello item2");
}
item3.onclick = function(){
 alert("hello item3");
}
</script>
事件委托
<ul id="list">
 <li id="item1" >item1</li>
 <li id="item2" >item2</li>
 <li id="item3" >item3</li>
</ul>
 
<script>
var item1 = document.getElementById("item1");
var item2 = document.getElementById("item2");
var item3 = document.getElementById("item3");
 
document.addEventListener("click",function(event){
 var target = event.target;
 if(target == item1){
 alert("hello item1");
 }else if(target == item2){
 alert("hello item2");
 }else if(target == item3){
 alert("hello item3");
 }
})
</script>

動態(tài)的添加DOM元素,不需要因為元素的改動而修改事件綁定笔横。

傳統(tǒng)寫法

<ul id="list">
 <li id="item1" >item1</li>
 <li id="item2" >item2</li>
 <li id="item3" >item3</li>
</ul>
<script>
var list = document.getElementById("list");
var item = list.getElementsByTagName("li");
for(var i=0;i<item.length;i++){
 (function(i){
 item[i].onclick = function(){
 alert(item[i].innerHTML);
 }
 })(i)
}
 
var node=document.createElement("li");
var textnode=document.createTextNode("item4");
node.appendChild(textnode);
list.appendChild(node);
 
</script>

點擊item1到item3都有事件響應(yīng)竞滓,但是點擊item4時,沒有事件響應(yīng)吹缔。說明傳統(tǒng)的事件綁定無法對動態(tài)添加的元素而動態(tài)的添加事件商佑。


事件委托

<ul id="list">
 <li id="item1" >item1</li>
 <li id="item2" >item2</li>
 <li id="item3" >item3</li>
</ul>
<script>
var list = document.getElementById("list");
document.addEventListener("click",function(event){
 var target = event.target;
 if(target.nodeName == "LI"){
 alert(target.innerHTML);
 }
})
var node=document.createElement("li");
var textnode=document.createTextNode("item4");
node.appendChild(textnode);
list.appendChild(node);
</script>

當點擊item4時,item4有事件響應(yīng)厢塘。說明事件委托可以為新添加的DOM元素動態(tài)的添加事件茶没。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市晚碾,隨后出現(xiàn)的幾起案子抓半,更是在濱河造成了極大的恐慌,老刑警劉巖迄薄,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件琅关,死亡現(xiàn)場離奇詭異,居然都是意外死亡讥蔽,警方通過查閱死者的電腦和手機涣易,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來冶伞,“玉大人新症,你說我怎么就攤上這事∠烨荩” “怎么了徒爹?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵荚醒,是天一觀的道長。 經(jīng)常有香客問我隆嗅,道長界阁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任胖喳,我火速辦了婚禮泡躯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘丽焊。我一直安慰自己较剃,他們只是感情好,可當我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布技健。 她就那樣靜靜地躺著写穴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪雌贱。 梳的紋絲不亂的頭發(fā)上啊送,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天,我揣著相機與錄音欣孤,去河邊找鬼删掀。 笑死,一個胖子當著我的面吹牛导街,可吹牛的內(nèi)容都是我干的披泪。 我是一名探鬼主播,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼搬瑰,長吁一口氣:“原來是場噩夢啊……” “哼款票!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起泽论,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤艾少,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后翼悴,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缚够,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年鹦赎,在試婚紗的時候發(fā)現(xiàn)自己被綠了谍椅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡古话,死狀恐怖雏吭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情陪踩,我是刑警寧澤杖们,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布悉抵,位于F島的核電站,受9級特大地震影響摘完,放射性物質(zhì)發(fā)生泄漏姥饰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一孝治、第九天 我趴在偏房一處隱蔽的房頂上張望媳否。 院中可真熱鬧,春花似錦荆秦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至吃媒,卻和暖如春瓤介,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背赘那。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工刑桑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人募舟。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓祠斧,卻偏偏與公主長得像,于是被迫代替她去往敵國和親拱礁。 傳聞我的和親對象是個殘疾皇子琢锋,可洞房花燭夜當晚...
    茶點故事閱讀 45,781評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 以下文章為轉(zhuǎn)載,對理解JavaScript中的事件處理機制很有幫助呢灶,淺顯易懂吴超,特分享于此。 什么是事件鸯乃? 事件(E...
    jxyjxy閱讀 3,042評論 1 10
  • JavaScript的事件是以一種流的形式存在的鲸阻,一個事件會有多個元素同時響應(yīng)。具體分為:捕獲型事件缨睡、冒泡型事件(...
    MrZengB閱讀 263評論 0 1
  • JavaScript的組成 JavaScript 由以下三部分組成:ECMAScript(核心):JavaScri...
    紋小艾閱讀 3,235評論 0 3
  • NARUTOne引言:js的事件機制在web開發(fā)中的出鏡率是很高鸟悴,但是要想給事件機制拍出高顏值的效果,還是很難的奖年。...
    迷緣火葉閱讀 607評論 0 0
  • Note:實現(xiàn)代碼之前可以先寫出偽代碼遣臼,可以節(jié)省很多時間。編程語言只是一種實現(xiàn)工具拾并。
    來個芒果閱讀 522評論 0 0