DOM事件流(不適用于IE8及以下版本IE)
“DOM2級事件”規(guī)定的事件流包括三個階段
當一個事件發(fā)生以后,它會在不同的DOM節(jié)點之間傳播(propagation)。這種傳播分成三個階段:
第一階段:從window對象傳導到目標節(jié)點,稱為“捕獲階段”(capture phase)。
第二階段:在目標節(jié)點上觸發(fā)趟章,稱為“目標階段”(target phase)。
第三階段:從目標節(jié)點傳導回window對象慎王,稱為“冒泡階段”(bubbling phase)蚓土。
綁定監(jiān)聽函數的方法
- HTML元素的on-屬性
//js中定義fun方法。
<script type="text/javascript">
function fun(){
console.log(this)
}
</script>
<div id="test" onclick="fun()"></div>
//等同于 使用元素節(jié)點的setAttribute方法 設置相應的屬性赖淤。
document.getElementById("test").setAttribute('onclick', 'fun()')
//等效于
document.getElementById("test").onclick=function onclick(event) {
fun()
}
- 屬性值是可執(zhí)行的代碼蜀漆,而不是監(jiān)聽函數,所以要執(zhí)行函數咱旱,不要忘記加上一對圓括號确丢。
- 事件觸發(fā)后" "中的代碼被執(zhí)行。定義好的fun函數被調用吐限。函數調用模式鲜侥,非嚴格模式fun函數中this指向window。
- 使用這個方法指定的監(jiān)聽函數诸典,只會在冒泡階段觸發(fā)描函。
- 若要訪問event對象。必須要這樣。在調用監(jiān)聽函數時間舀寓,一定要顯示傳入event對象
<div id="test" onclick="fun(event)"></div>
- Element節(jié)點的事件屬性
Element節(jié)點有事件屬性胆数,同樣可以指定監(jiān)聽函數。
div.onclick = function(){ console.log(this)};
- 事件觸發(fā)后執(zhí)行該元素節(jié)點的onclick方法基公。方法調用模式 幅慌, 函數中this指向該節(jié)點對象。
- 使用這個方法指定的監(jiān)聽函數轰豆,只會在冒泡階段觸發(fā)胰伍。
- 只能給元素節(jié)點和document節(jié)點指定監(jiān)聽函數,不能給文本節(jié)點指定監(jiān)聽函數酸休。
- 使用addEventListener方法也可以在骂租,定義一個特定事件的監(jiān)聽函數。
addEventListener是推薦的指定監(jiān)聽函數的方法斑司。它有如下優(yōu)點:
可以針對同一個事件渗饮,添加多個監(jiān)聽函數。
能夠指定在哪個階段(捕獲階段還是冒泡階段)觸發(fā)監(jiān)聽函數,默認為false(只在冒泡階段被觸發(fā))宿刮。
除了DOM節(jié)點(所有DOM節(jié)點)互站,還可以部署在window、XMLHttpRequest等對象上面僵缺,等于統(tǒng)一了整個JavaScript的監(jiān)聽函數接口胡桃。
- addEventListener 添加的方法只能用remoEventListener 移除
事件綁定時的this指向
以下寫法的this對都指向Element節(jié)點:
// JavaScript代碼
element.onclick = printelement.addEventListener('click', print, false)
element.onclick = function () {console.log(this.id);}
// HTML代碼
<element onclick="console.log(this.id)">
以下寫法的this,都指向全局對象磕潮。
// JavaScript代碼
element.onclick = function (){ doSomething() };
element.setAttribute('onclick', 'doSomething()');
// HTML代碼
<element onclick="doSomething()">
在監(jiān)聽函數中翠胰,currentTarget屬性實際上等同于this對象。
IE8及以下版本自脯,事件對象不作為參數傳遞之景,而是通過window對象的event屬性讀取,并且事件對象的target屬性叫做srcElement屬性膏潮。所以锻狗,以前獲取事件信息,往往要寫成下面這樣戏罢。
var actualEvent = event || window.event;
var actualTarget = actualEvent.target || actualEvent.srcElement;
//...
}```
其他瀏覽器中事件對象會作為參傳遞屋谭,同時會將值賦給window.event
#####preventDefault():
preventDefault方法取消瀏覽器對當前事件的默認行為,比如點擊鏈接 后龟糕,瀏覽器跳轉到指定頁面,或者按一下空格鍵悔耘,頁面向下滾動一段距離讲岁。該方法生效的前提是,事件的cancelable屬性為true,如果為false缓艳,則調用該方法沒有任何效果校摩。
#####event.stopPropagation():
stopPropagation方法阻止事件在DOM中繼續(xù)傳播,防止再觸發(fā)定義在別的節(jié)點上的監(jiān)聽函數阶淘,但是不包括在當前節(jié)點上新定義的事件監(jiān)聽函數衙吩。
function stopEvent(e) {
e.stopPropagation();
}
el.addEventListener('click', stopEvent, false);
將上面函數指定為監(jiān)聽函數,會阻止事件進一步冒泡到el節(jié)點的父節(jié)點溪窒。
#####event.cancelBubble=true;
event.cancelBubble=true 阻止事件冒泡坤塞。不同于event.stopPropagation() 它阻止的只是冒泡階段的事件傳遞,
關于阻止事件傳遞澈蚌,一直有如下謬論:
>event.cancelBubble=true用于ie的阻止冒泡事件摹芙,
event.stopPropagation()用于firefox和chrome等其他瀏覽器。
ie9及以上版本IE宛瞄,和其他瀏覽器(chrome Firefox safari opera Edge)中都可以用event.cancelBubble=true浮禾;取消事件冒泡。除此之外份汗,這些瀏覽量器相對于低版本IE 還有了event.stopPropagation()方法 用于阻止事件在DOM中繼續(xù)傳播包括捕獲和冒泡盈电。
#####event.stopImmediatePropagation()
stopImmediatePropagation
方法阻止同一個事件的其他監(jiān)聽函數被調用。
如果同一個節(jié)點對于同一個事件指定了多個監(jiān)聽函數杯活,這些函數會根據添加的順序依次調用匆帚。只要其中有一個監(jiān)聽函數調用了stopImmediatePropagation方法,其他的監(jiān)聽函數就不會再執(zhí)行了轩猩。
function l1(e){
e.stopImmediatePropagation();
}
function l2(e){
console.log('hello world');
}el.addEventListener('click', l1, false);
el.addEventListener('click', l2, false);
上面代碼在el節(jié)點上卷扮,為click事件添加了兩個監(jiān)聽函數l1和l2。由于l1調用了stopImmediatePropagation方法均践,所以l2不會被調用晤锹。
#####return false
可以同時取消事件冒泡和默認事件