㈠事件流
▶事件:是文檔和瀏覽器窗口中發生的,特定的交互瞬間。
▶事件流:描述的是從頁面中接受事件的順序
⑴DOM事件冒泡
定義:事件最開始由最具體的元素(文檔中嵌套層次最深的那個節點)接受,然后逐級向上傳播至最不具體的那個節點(文檔)。
具體講解:
代碼:
<html> <head> <title>事件流<title> <meta charset="utf-8"></head> <body> <div id="box"> <input type="button" value="按鈕" id="btn"> </div> </body> </html>
說明:點擊按鈕,瀏覽器就會認為:你點按鈕的同時,也點擊了包含這個按鈕的這個容器(“div”),那么你點了這個div以后,它又認為你點了整個HTML了,那么你點了整個HTML,它又認為你點了整個document。也就是說:click事件在input上觸發,那么它會一級一級往上冒,最后直到冒到document。
⑵DOM事件捕獲
定義:不太具體的節點應該更早接受到事件,而最具體的節點最后接受到事件。
具體講解:
代碼:
<html> <head> <title>事件流<title> <meta charset="utf-8"></head> <body> <div id="box"> <input type="button" value="按鈕" id="btn"> </div> </body> </html>
說明:用事件捕獲的思想:它認為最先把事件用document接收了,然后讓HTML接收了,然后又讓body接收,然后又讓div接收了,最后才被input接收了。
㈡事件處理程序
⑴ HTML事件處理程序
含義:你的事件直接加在HTML結構里
具體解釋:
代碼:
<html> <head> <title>事件流<title> <meta charset="utf-8"></head> <body> <div id="box"> <input type="button" value="按鈕" id="btn" onclick="alert('hello')"> </div> </body> </html>
說明:直接將onclick事件加在input標簽上,而且是在HTML結構里
注:並不是所有要執行的JS代碼都應該寫在這個地方,也可以把它封裝在這個函數內
代碼:
<html> <head> <title>事件流<title> <meta charset="utf-8"></head> <body> <div id="box"> <input type="button" value="按鈕" id="btn" onclick="showMessage()"> </div> <script> function showMessage(){ alert('hello world!'); } </script> </body> </html>
HTML事件的缺點:HTML和JS代碼緊密的耦合在一起
具體解釋:如果要更換事件處理程序,就要修改兩個地方:HTML代碼和JS函數
⑵ DOM0級事件處理程序
這種方法是一種較為傳統的方式:把一個函數賦值給一個事件的處理程序屬性
這是用的比較多的方法,原因是簡單,跨瀏覽器的優勢
代碼示例:
<html> <head> <title>事件流<title> <meta charset="utf-8"></head> <body> <div id="box"> <input type="button" value="按鈕" id="btn" onclick="showMes()"> <input type="button" value="按鈕2" id="btn2" > </div> <script> function showMes(){ alert('hello world!'); } var btn2=document.getElementById('btn2'); //取得btn2按鈕對象 btn2.onclick=function(){ //給btn2添加onclick屬性 alert('這是通過DOM0級添加的事件!'); } btn2.onclick=null; //刪除onclick屬性 </script> </body> </html>
優點:1)沒有HTML事件的缺點
2)可以給一個元素上添加多個事件處理程序,這些事件處理程序會按順序執行。
⑶ DOM2級事件處理程序
①DOM2級事件定義了兩個方法:
用於處理指定和刪除事件處理程序的操作
addEventListener() 和 removeEventListener()。
②接收三個參數:
1) 要處理的事件名
2) 作為事件處理程序的函數
3) 布爾值(true表示在捕獲階段調用事件處理程序;false表示在冒泡階段調用事件處理程序)
③代碼示例:
<html> <head> <title>事件流<title> <meta charset="utf-8"></head> <body> <div id="box"> <input type="button" value="按鈕" id="btn" onclick="showMes()"> <input type="button" value="按鈕2" id="btn2" > <input type="button" value="按鈕3" id="btn3" > </div> <script> function showMes(){ alert('hello world!'); } var btn2=document.getElementById('btn2'); var btn3=document.getElementById('btn3'); btn2.onclick=function(){ alert('這是通過DOM0級添加的事件!'); } btn2.onclick=null; //DOM2級事件 btn3.addEventListener('onclick',showMes,false); //給btn3添加一個事件監聽程序 兼容各種瀏覽器 //刪除事件 btn3.removeEventListener('onclick',showMes,false); </script> </body> </html>
④優點:可以給一個元素上添加多個事件處理程序,這些事件處理程序會按順序執行。
代碼示例:
<html> <head> <title>事件流<title> <meta charset="utf-8"></head> <body> <div id="box"> <input type="button" value="按鈕" id="btn" onclick="showMes()"> <input type="button" value="按鈕2" id="btn2" > <input type="button" value="按鈕3" id="btn3" > </div> <script> function showMes(){ alert('hello world!'); } var btn2=document.getElementById('btn2'); var btn3=document.getElementById('btn3'); btn2.onclick=function(){ alert('這是通過DOM0級添加的事件!'); } btn2.onclick=null; //DOM2級事件 btn3.addEventListener('onclick',showMes,false); btn3.addEventListener('onclick',function(){ alert(this.value);引用被觸發的元素 },false); </script> </body> </html>
注意:在IE瀏覽器中不起作用。
⑷IE事件處理程序
attachEvent()添加事件
detachEvent()刪除事件
②接收相同的兩個參數:
事件處理程序的名稱和事件處理程序的函數
③不使用第三個參數的原因:IE8及以更早的瀏覽器版本只支持事件冒泡!
代碼示例:
<html> <head> <title>事件流<title> <meta charset="utf-8"></head> <body> <div id="box"> <input type="button" value="按鈕" id="btn" onclick="showMes()"> <input type="button" value="按鈕2" id="btn2" > <input type="button" value="按鈕3" id="btn3" > </div> <script> function showMes(){ alert('hello world!'); } var btn2=document.getElementById('btn2'); var btn3=document.getElementById('btn3'); btn2.onclick=function(){ alert('這是通過DOM0級添加的事件!'); } btn2.onclick=null; //IE事件處理程序 btn3.attachEvent('onclick',showMes); btn3.detachEvent('onclick',showMes); </script> </body> </html>
注意:只在IE瀏覽器和Opera瀏覽器中使用
⑸跨瀏覽器的事件處理程序
①方法:恰當的使用能力檢測
②問題:如何實現跨瀏覽器解決事件處理程序?
通過將增加和刪除封裝在一個對象里面,封裝了兩個方法,每個方法都進行了能力檢測,你支持這個方法,就用這個方法,不支持這個方法,就用所支持的方法。
③代碼示例:
<html> <head> <title>事件流<title> <meta charset="utf-8"></head> <body> <div id="box"> <input type="button" value="按鈕" id="btn" onclick="showMes()"> <input type="button" value="按鈕2" id="btn2" > <input type="button" value="按鈕3" id="btn3" > </div> <script> function showMes(){ alert('hello world!'); } var btn2=document.getElementById('btn2'); var btn3=document.getElementById('btn3'); btn2.onclick=function(){ alert('這是通過DOM0級添加的事件!'); } btn2.onclick=null; //跨瀏覽器事件處理程序 vareventUtil={ //添加句柄 addHandler:function(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false); }else if(element.attachEvent){ element.attachEvent('on'+type,handler); }else{ element['on'+type]=handler; } }, //刪除句柄 removeHandler:function(element,type,handler){ if(element.removeEventListener){ element.removeEventListener(type,handler,false); }else if(element.detachEvent){ element.detachEvent('on'+type,handler); }else{ element['on'+type]=null; } } } eventUtil.addHandler(btn3,'click',showMes); eventUtil.removeHandler(btn3,'click',showMes); </script> </body> </html>