Javascript與HTML之間的交互是通過事件實現的。
事件,就是文檔或瀏覽器窗口中發生的一些特定的交互瞬間。
可以使用偵聽器來預定事件,以便事件發生時執行相應代碼。
事件流
JS事件流最早要從IE和網景公司的瀏覽器大戰說起,IE提出的是冒泡流,而網景提出的是捕獲流,后來在W3C組織的統一之下,JS支持了冒泡流和捕獲
流,但是目前低版本的IE瀏覽器還是只能支持冒泡流(IE6,IE7,IE8均只支持冒泡流),所以為了能夠兼容更多的瀏覽器,建議大家使用冒泡流。
事件流原理圖如下:
從圖中我們可以知道
1、一個完整的JS事件流是從window開始,最后回到window的一個過程
2、事件流被分為三個階段(1~5)捕獲過程、(5~6)目標過程、(6~10)冒泡過程
3、在冒泡過程中6比7早觸發。
下面舉個例子說明js中的事件
<body> <div class="parent"> parent <div class="child">child</div> </div> </body> <script type="text/javascript"> var oParent=document.getElementsByClassName("parent")[0]; var oChild=document.getElementsByClassName("child")[0]; oParent.oclick=function(){ console.log("parent"); } oParent.onclick=function(){ console.log("parent-2"); } oChild.onclick=function(){ console.log("chlid"); } </script>
點擊child運行結果是:
上面的例子是Dom0級事件,在Dom0級事件中一個元素相同的事件只能綁定一次如(onclick),並且綁定的是最后綁定的那個事件,這個有點像jquery
中的html方法一樣,后面的會覆蓋掉前面的內容一樣。在Dom0級事件里只有事件冒泡沒有事件捕獲。
在Dom2級事件里支持事件冒泡和事件捕獲
oParent.addEventListener("click",function(){ console.log("parent"); },false); oParent.addEventListener("click",function(){ console.log("parent-2"); },false); oChild.addEventListener("click",function(){ console.log("chlid"); },false);
執行結果:
這里是發生了事件冒泡,點擊child,先執行了child后輸出了parent和parent-2,同時可以看出Dom2級事件是支持添加同名事件的按照先后順序執
行。addEventListener是Dom2里添加事件監聽的寫法可以接受三個參數,第一個參數是事件名稱,第二個是事件處理函數,第三個參數是布爾值true是
設置事件捕獲,false是設置事件冒泡,默認情況下是false。IE里面添加監聽事件是attachEvent但是IE不支持事件捕獲,所以attachEvent只有前兩
個參數,不能設置true和false,同時事件名也要加上on。比如addEventListener的單擊事件是click,而attachEvent的單擊事件是onclick。有添
加監聽事件就有移除監聽事件,與addEventListener相對的是removeEventListener,與attachEvent相對應的是deatchEvent這兩個寫法與上面
類似,需要注意的是移除事件時要同時刪除事件名和對應的方法。
為了解決和IE的兼容問題同城會將兩種寫法封裝成一個函數進行調用,因為IE不支持事件捕獲,所以盡量使用事件冒泡以解決兼容問題。
下面是網上的封裝示例可以參考一下
var EventUtil = { 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; } } };
這兩個方法首先都會檢測傳入的元素中是否存在DOM2級方法。如果存在DOM2級方法,則使用該方法;如果存在的是IE的方法,則采取第二種方案。最后
一種可能就是DOM0級方法,此時使用的是方括號語法來將屬性名指定為事件處理程序,或者將屬性設置為null。