解釋以下概念:事件傳播機(jī)制讹剔、阻止傳播吊趾、取消默認(rèn)事件三痰、事件代理
事件傳播機(jī)制
事件傳播機(jī)制分為三個(gè)階段
- 事件捕獲階段:事件被從document一直向下傳播到目標(biāo)元素,在這過程中依次檢查經(jīng)過的節(jié)點(diǎn)是否注冊(cè)了該事件的監(jiān)聽函數(shù),若有則執(zhí)行梗逮。(ie低版本沒有捕獲)
- 事件處理階段:事件到達(dá)目標(biāo)元素,執(zhí)行目標(biāo)元素的事件處理函數(shù).
- 冒泡傳播:從捕獲到事件源的元素開始往父級(jí)元素進(jìn)行事件冒泡,DOM0級(jí)事件中绣溜,事件綁定函數(shù)的觸發(fā)都發(fā)生在冒泡階段
阻止傳播
stopPropagation()
取消事件進(jìn)一步捕獲或冒泡
阻止默認(rèn)事件
preventDefault()
取消事件默認(rèn)行為
- 什么是事件默認(rèn)行為?
-
a鏈接
默認(rèn)跳轉(zhuǎn) - type =
submit
默認(rèn)提交表單 其他瀏覽器默認(rèn)行為...
-
我們不希望瀏覽器默認(rèn)做什么事情,我們就給它綁定事件,怎么綁定呢?preventDefault()
<a >baidu</a>
<script>
document.querySelector('a').onclick= function(e){
//阻止默認(rèn)事件
e.preventDefault()
//點(diǎn)擊時(shí)打印鏈接
console.log(this.href)
if(/baidu.com/.test(this.href)){
location.href = this.href
}
}
</script>
<form action="/login">
<input type="text" name="username">
<input type="submit">
</form>
<script>
document.querySelector('form').addEventListener('submit', function(evt){
//阻止默認(rèn)事件
evt.preventDefault()
if(document.querySelector('input[name=username]').value === 'jirengu'){
this.submit()
}
})
</script>
事件代理
要理解事件代理,首先要明白什么是事件冒泡:當(dāng)一個(gè)元素上的事件被觸發(fā)的時(shí)候慷彤,比如說鼠標(biāo)點(diǎn)擊了一個(gè)按鈕,同樣的事件將會(huì)在那個(gè)元素的所有祖先元素中被觸發(fā)涮毫。這一過程被稱為事件冒泡瞬欧。
<ul id="oul">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
(function(){
var oUl=document.getElementById("oul");
oUl.addEventListener('click',show,false);
function show(e) {
var targetElement=e.target||e.srcElement;
if(targetElement.nodeName.toLowerCase()==="li"){
alert(targetElement.innerHTML);
}
}
})();
</script>
看上面的這個(gè)例子,我把click
事件綁定在了父元素ul
上,而不是li
上,于是,當(dāng)我點(diǎn)擊任何一個(gè)li標(biāo)簽
(不管是動(dòng)態(tài)生成的還是之前就有的)是罢防,這個(gè)事件就像泡泡一樣艘虎,冒啊冒。由于我這里給ul綁定了onlick
咒吐,那么這時(shí)野建,ul會(huì)捕獲冒泡上來的onclick事件
。
我們來看一下事件代理的步驟:
- 父元素綁定事件
- 父元素知道事件的實(shí)際發(fā)生目標(biāo)是誰
- 我們要對(duì)目標(biāo)進(jìn)行判斷恬叹,如果是我們需要的元素候生,則發(fā)生回調(diào)函數(shù)
事件代理的優(yōu)點(diǎn):
- 性能不小心得到了優(yōu)化
- 動(dòng)態(tài)添加的元素也能綁定事件了
寫一個(gè) Demo,演示事件傳播的過程绽昼,演示阻止傳播的效果
image
//html
<body>
<style>
.container,
.box,
.target{
border: 1px solid;
padding: 10px;
}
</style>
<button id="btn">click</button>
<div class="container">
container
<div class="box">
box
<div class="target">target</div>
</div>
</div>
</body>
//js
function $(selector){
return document.querySelector(selector)
}
var btn = $('#btn')
btn.onclick = function (e){
console.log(e)
}
btn.addEventListener('click', function(evt){
console.log(this)
console.log(btn)
console.log(evt.target)
})
$('.container').addEventListener('click', function(e){
console.log('contianer click.. in 捕獲階段')
}, true)
$('.box').addEventListener('click', function(e){
//e.stopPropagation() //阻止傳播
console.log('box click.. in 捕獲階段')
}, true)
$('.target').addEventListener('click', function(e){
console.log('target click.. in 捕獲階段')
}, true)
$('.container').addEventListener('click', function(e){
console.log('contianer click.. in 冒泡階段')
}, false)
$('.box').addEventListener('click', function(e){
//e.stopPropagation() //阻止傳播
console.log('box click.. in 冒泡階段')
}, false)
$('.target').addEventListener('click', function(e){
console.log('target click.. in 冒泡階段')
}, false)