事件
用戶交互行爲,用戶或瀏覽器自身執行的某種動作
事件流
頁面接收事件的順序,事件觸發的順序,
分爲 事件冒泡(子級先觸發,冒泡到父級)和事件捕獲(父級先觸發,再到達子級) 先捕獲->處於目標階段 -> 再冒泡
- 事件冒泡:事件按照從最特定的事件目標到最不特定的事件目標(document對象)的順序觸發,子級元素先觸發
- 事件捕獲:事件從最不精確的對象(document對象)開始觸發,然後到最精確(也可以在窗口級別捕獲事件,不過必須由開發人員特別指定),父級元素先觸發
- 事件捕獲階段:事件從最上一級標籤開始往下查找,直到捕獲到事件目標(target)。
- 事件冒泡階段:事件從事件目標(target)開始,往上冒泡直到頁面的最上一級標
事件模型的各個階段
捕獲階段-目標階段-冒泡階段
事件處理程序
響應某個事件的函數
- HTML(在標籤內嵌入事件)
- DOM0(通過DOM操作,給節點上添加事件)
- DOM2(addEventlistener(‘click’, fn, false))
- IE(attachEvent(‘onclick’, fn))
- 跨瀏覽器(EventUtil函數)
// 跨瀏覽器處理 綜上,兼容DOM和IE的不同處理,
var EventUtil = {
// 跨瀏覽器 前兩個是兼容 事件對象,中間兩個是兼容 事件冒泡或默認行爲 ,後兩個是兼容 事件處理程序
getEvent: function(event){
return event ? event : window.event;
},
getTarget: function(event){
return event ? event.target : event.srcElement;
},
stopPropagation: function(event){
if(event){
return event.stopPropagation();
} else {
return event.cancelBubble = true;
}
},
preventDefault: function(event){
if(event){
return event.preventDefault();
} else {
return event.returnValue = false;
}
},
addHandler: function(element, type, handler){
if(element.addEventListener) {
return element.addEventListener(type, handler, false) // DOM2
} else if(element.attachEvent) {
return element.attachEvent("on"+type, handler) // IE
} else {
return element["on"+type] = handler // DOM0
}
},
removeHandler: function(element, type, handler){
if(element.removeEventListener) {
return element.removeEventListener(type, handler, false) // DOM2
} else if(element.detachEvent) {
return element.detachEvent("on"+type, handler) // IE
} else {
return element["on"+type] = null // DOM0
}
}
}
事件對象
觸發事件 event 對象的所有信息
DOM事件模型中的事件對象常用屬性:
- type用於獲取事件類型
- target獲取事件目標
- stopPropagation()阻止事件冒泡
- preventDefault()阻止事件默認行爲
IE事件模型中的事件對象常用屬性:
- type用於獲取事件類型
- srcElement獲取事件目標
- cancelBubble = true 阻止事件冒泡
- returnValue = false 阻止事件默認行爲
W3C模型是將兩者進行中和,在W3C模型中,任何事件發生時,先從頂層開始進行事件捕獲,直到事件觸發到達了事件源元素。然後,再從事件源往上進行事件冒泡,直到到達document。
IE只支持事件冒泡,不支持事件捕獲,它也不支持addEventListener函數,不會用第三個參數來表示是冒泡還是捕獲,它提供了另一個函數attachEvent。
ele.attachEvent(“onclick”, doSomething2);
使用jquery,既停止冒泡又阻止默認行爲
$("#testC").on('click',function(){
return false;
});
ele.addEventListener(‘click’,doSomething2,true)
true=捕獲 false=冒泡
事件類型
- UI(User Interface,用戶界面)事件,當用戶與頁面上的元素交互時觸發; 如resize,scroll
- 焦點事件,當元素獲得或失去焦點時觸發; 如blur (在元素失去焦點時觸發,這個事件不會冒泡)
- 鼠標事件,當用戶通過鼠標在頁面上執行操作時觸發;如click
- 滾輪事件,當使用鼠標滾輪(或類似設備)時觸發;
- 文本事件,當在文檔中輸入文本時觸發;
- 鍵盤事件,當用戶通過鍵盤在頁面上執行操作時觸發;
- 合成事件,當爲 IME(Input Method Editor,輸入法編輯器)輸入字符時觸發;
- 變動(mutation)事件,當底層 DOM 結構發生變化時觸發。
事件委託
事件委託就是利用事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件
減少與dom交互,提高性能
頁面上有這麼一個節點樹,div>ul>li>a;比如給最裏面的a加一個click點擊事件,那麼這個事件就會一層一層的往外執行,執行順序a>li>ul>div,有這樣一個機制,那麼我們給最外面的div加點擊事件,那麼裏面的ul,li,a做點擊事件的時候,都會冒泡到最外層的div上,所以都會觸發,這就是事件委託,委託它們父級代爲執行事件
xs.on事件=function(){} //相當於寫一個函數。
處理兼容性問題
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
window.onload = function(){
var Oul = document.getElementById('oul');
//var Oul = document.getElementsByTagName('ul');
//想要使用addEventListener,必須是dom元素,獲取的是id值
Oul.addEventListener('click',function(ev){
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
//不能直接使用target,必須有所轉換再去匹配
if(target.nodeName.toLowerCase() == "li"){
alert(target.innerHTML);
}
},false);
// Oul.οnclick= function(){
// alert('aaa')
// }
}
跨瀏覽器實現:
<ul id="weituo">
<li>子節點1</li>
<li>子節點2</li>
<li>子節點3</li>
</ul>
var ww = document.getElementById("weituo");
var handleee = function(e){
var event = EventUtil.getEvent(e);
var target = EventUtil.getTarget(e);
// 判斷是否匹配目標元素
console.log(target.nodeName);
if (target.nodeName.toLocaleLowerCase() === 'li') {
console.log('the content is: ', target.innerHTML);
}
}
EventUtil.addHandler(ww, "click", handleee)
ps: 整理自《JavaScript高級程序設計》
關注我獲取更多前端資源和經驗分享
感謝大佬們閱讀,希望大家頭髮濃密,睡眠良好,情緒穩定,早日實現財富自由~