簡(jiǎn)介
事件是可以被 JavaScript 偵測(cè)到的行為近哟。
網(wǎng)頁(yè)中的每個(gè)元素都可以產(chǎn)生某些可以觸發(fā) JavaScript 函數(shù)或程序的事件。
事件通常與函數(shù)配合使用钱豁,當(dāng)事件發(fā)生時(shí)函數(shù)才會(huì)執(zhí)行耻卡。
執(zhí)行JS 事件的方式:
- HTML 事件屬性可以直接執(zhí)行 JavaScript 代碼
- HTML 事件屬性可以調(diào)用 JavaScript 函數(shù)
- 你可以為 HTML 元素指定自己的事件處理程序
- 你可以阻止事件的發(fā)生。
- 等等 ...
常用的JS事件 | type |
---|---|
鼠標(biāo)單擊事件 | onclick |
鼠標(biāo)經(jīng)過(guò)事件 | onmouseover |
鼠標(biāo)移開事件 | onmouseout |
聚焦事件 | onfocus |
失焦事件 | onblur |
加載事件 | onload |
刷新頁(yè)面 | onunload(貌似只對(duì)IE有效) |
關(guān)閉頁(yè)面 | onbeforeunload(貌似只對(duì)IE有效) |
事件流
事件流描述的是從頁(yè)面中接受事件的順序牲尺。
- IE 的事件流是事件冒泡流卵酪,事件由子元素獲取并沿DOM樹向上傳播。即事件最開始由最具體的元素(文檔中嵌套層次最深的那個(gè)節(jié)點(diǎn))接收谤碳,然后逐級(jí)向上轉(zhuǎn)播至最不具體的節(jié)點(diǎn)(document)凛澎,用
stopPropagation()
方法終止冒泡。 - Netscape 的事件流是事件捕獲流估蹄,事件由根元素獲取并沿DOM樹向下分發(fā)塑煎。與事件冒泡流相反,事件捕獲的思想是不太具體的節(jié)點(diǎn)(document)應(yīng)該更早接收到事件臭蚁,而最具體的節(jié)點(diǎn)最后接收到事件最铁。已經(jīng)不適用了
Event 對(duì)象
HTML DOM Event 對(duì)象
header 1 | header 2 |
---|---|
事件 | event |
事件目標(biāo) | event.target |
添加事件 | element.addEventListener(type, listener, false) |
移除事件 | element.removeEventListener(type, listener, false) |
阻止事件冒泡 | event.stopPropagation() |
取消默認(rèn)行為 | event.preventDefault() |
IE 中的 Event 對(duì)象
header 1 | header 2 |
---|---|
事件 | window.event |
事件目標(biāo) | event.srcElement |
添加事件 | element.attachEvent('on' + type, listener) |
移除事件 | element.detachEvent('on' + type, listener) |
阻止事件冒泡 | event.cancelBubble = true |
取消默認(rèn)行為 | event.returnValue = false |
事件處理程序
HTML 事件處理程序
事件直接寫在html的元素里面,缺點(diǎn):html和js代碼緊密的耦合在一起垮兑。
<a href="" onclick="alert('msg');">測(cè)試</a>
0級(jí) DOM事件處理程序
把一個(gè)函數(shù)賦值給一個(gè)事件的處理程序?qū)傩岳湮荆瑑?yōu)點(diǎn):比較簡(jiǎn)單,跨瀏覽器支持系枪。缺點(diǎn):不能添加多個(gè)事件處理程序雀哨,最后一個(gè)事件會(huì)覆蓋前面的事件
document.getElementById('id').onclick = function () {
alert(1);
}
2級(jí) DOM事件處理程序
通過(guò) addeventlistener()
添加事件,只能用 removeEventlistener()
刪除此事件。它們都接收三個(gè)參數(shù):要處理的事件名event(不加'on')雾棺、作為事件處理程序的函數(shù)function(優(yōu)點(diǎn):可以添加多個(gè)事件處理程序膊夹,)和一個(gè)布爾值useCapture。布爾參數(shù)僅僅在現(xiàn)代瀏覽器最近的幾個(gè)版本中是可加可不加的捌浩,并且true代表該事件在捕獲階段執(zhí)行放刨,false代表在冒泡階段執(zhí)行,建議寫false尸饺,因?yàn)橛行g覽器只有冒泡階段进统。
target.addEventListener(type, listener[, useCapture]);
target.removeEventListener(type, listener[, useCapture]);
IE 事件處理程序
IE8 及更早IE版本不支持 addEventListener() 方法,Opera 7.0 及 Opera 更早版本也不支持浪听。 但是螟碎,對(duì)于這些不支持該函數(shù)的瀏覽器,你可以使用 attachEvent()
方法來(lái)添加事件句柄迹栓。通過(guò) attachEvent()
添加事件抚芦,只能用 detachEvent()
刪除此事件。這兩個(gè)方法接收相同的兩個(gè)參數(shù):事件處理程序名稱 type 與事件處理函數(shù) function迈螟,不支持第三個(gè)參數(shù)的原因:IE8--只支持冒泡冒泡流叉抡。
element.attachEvent(type, function)
element.detachEvent(type, function)
事件代理和委托
當(dāng)我們需要對(duì)很多元素添加事件的時(shí)候,可以通過(guò)將事件添加到它們的父節(jié)點(diǎn)而將事件委托給父節(jié)點(diǎn)來(lái)觸發(fā)處理函數(shù)答毫。這主要得益于瀏覽器的事件冒泡機(jī)制褥民。
<div id="box">
<p>Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet.</p>
</div>
<script>
let box = document.getElementById('box');
box.addEventListener('click', function (e) {
// 檢查事件源e.targe是否為P
if (e.target.nodeName === 'P') {
// 真正的處理過(guò)程在這里
alert('p');
}
})
</script>
跨瀏覽器兼容的事件處理程序(能力檢測(cè))
/*
* @Author: bxm09
* @Date: 2017-03-24 15:51:37
* @Last Modified by: bxm09
* @Last Modified time: 2017-07-24 13:16:04
* @Desc 跨瀏覽器兼容的事件處理程序(能力檢測(cè))
*/
var eventshiv = {
// event兼容
getEvent: function(event) {
return event ? event : window.event;
},
// type兼容
getType: function(event) {
return event.type;
},
// target兼容
getTarget: function(event) {
return event.target ? event.target : event.srcelem;
},
/**
* 添加事件句柄
* 2級(jí) DOM -> IE -> 0級(jí) DOM
*/
addHandler: function(elem, type, listener) {
if (elem.addEventListener) {
elem.addEventListener(type, listener, false);
} else if (elem.attachEvent) {
elem.attachEvent('on' + type, listener);
} else {
// 在這里由于.與'on'字符串不能鏈接,只能用 []
elem['on' + type] = listener;
}
},
// 移除事件句柄
removeHandler: function(elem, type, listener) {
if (elem.removeEventListener) {
elem.removeEventListener(type, listener, false);
} else if (elem.detachEvent) {
elem.detachEvent('on' + type, listener);
} else {
elem['on' + type] = null;
}
},
/**
* 添加事件代理
*/
addAgent: function (elem, type, agent, listener) {
elem.addEventListener(type, function (e) {
if (e.target.matches(agent)) {
listener.call(e.target, e); // this 指向 e.target
}
});
},
/**
* 取消默認(rèn)行為
* 非IE -> IE
*/
preventDefault: function(event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
/**
* 阻止事件冒泡
* 非IE -> IE
*/
stopPropagation: function(event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
};
console.log('eventshiv.js 文件加載成功洗搂!');