解釋以下概念:事件傳播機(jī)制宴倍、阻止傳播直奋、取消默認(rèn)事件、事件代理九杂。
- 事件傳播機(jī)制主要有三種:
- 事件冒泡:事件開始時(shí)由最具體的元素接收颁湖,然后逐級向上傳播到較為不具體的元素(從小到大)
- 事件捕獲:不太具體的節(jié)點(diǎn)更早接收事件,而最具體的元素最后接收事件例隆,和事件冒泡相反(從大到猩唷)
- DOM事件流:DOM2 級事件規(guī)定事件流包括三個(gè)階段,事件捕獲階段镀层,處于目標(biāo)階段镰禾,事件冒泡階段,首先發(fā)生的是事件捕獲,為截取事件提供機(jī)會吴侦,然后是實(shí)際目標(biāo)接收事件屋休,最后是冒泡階段(標(biāo)準(zhǔn)瀏覽器現(xiàn)在都使用 DOM 事件流,IE 不支持事件流备韧,只支持事件冒泡)
2.阻止傳播
- stopPropagation() 取消事件進(jìn)一步捕獲或冒泡
-
取消默認(rèn)事件
preventDefault() 取消事件默認(rèn)行為 -
事件代理
通過事件冒泡(或者事件捕獲)給父元素添加事件監(jiān)聽劫樟,e.target 指向引發(fā)觸發(fā)事件的元素。
寫一個(gè) Demo盯蝴,演示事件傳播的過程毅哗,演示阻止傳播的效果听怕。
<style>
.container,
.box,
.target{
border: 1px solid;
padding: 20px;
}
</style>
<button id="btn">click</button>
<div class="container">
container
<div class="box">
box
<div class="target">target</div>
</div>
</div>
<script>
function $(selector){
return document.querySelector(selector)
}
var btn = $('#btn')
btn.addEventListener('click',function(evt){
console.log(evt.target)
})
$('.container').addEventListener('click',function(e){
console.log('container click in 捕獲階段')
},true)
$('.box').addEventListener('click',function(e){
// 在此處添加 e.stopPropagation()則捕獲階段止于 box 捕獲階段 而不再向下出現(xiàn)"target click in 捕獲階段"和所有冒泡階段
// 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('container click in 冒泡階段')
},false)
$('.box').addEventListener('click',function(e){
// 在此處添加 e.stopPropagation()則冒泡階段止于 box 而不再向上出現(xiàn)"container click in 冒泡階段"
// e.stopPropagation()
console.log('box click in 冒泡階段')
},false)
$('.target').addEventListener('click',function(e){
console.log('target click in 冒泡階段')
},false)
</script>
解釋DOM2事件傳播機(jī)制捧挺。
補(bǔ)全代碼,要求:
當(dāng)點(diǎn)擊按鈕開頭添加時(shí)在<li>這里是</li>元素前添加一個(gè)新元素尿瞭,內(nèi)容為用戶輸入的非空字符串闽烙;當(dāng)點(diǎn)擊結(jié)尾添加時(shí)在最后一個(gè) li 元素后添加用戶輸入的非空字符串.
當(dāng)點(diǎn)擊每一個(gè)元素li時(shí)控制臺展示該元素的文本內(nèi)容。
<ul class="ct">
<li>這里是</li>
<li>饑人谷</li>
<li>任務(wù)班</li>
</ul>
<input class="ipt-add-content" placeholder="添加內(nèi)容"/>
<button id="btn-add-start">開頭添加</button>
<button id="btn-add-end">結(jié)尾添加</button>
<script>
//你的代碼
</script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<ul class="ct">
<li>這里是</li>
<li>饑人谷</li>
<li>任務(wù)班</li>
</ul>
<input class="ipt-add-content" placeholder="添加內(nèi)容"/>
<button id="btn-add-start">開頭添加</button>
<button id="btn-add-end">結(jié)尾添加</button>
<script>
function $(query){
return document.querySelector(query);
}
var ul = $('.ct')
var addContent = $('.ipt-add-content')
var addStart = $('#btn-add-start')
var addEnd = $('#btn-add-end')
addStart.addEventListener('click',function(){
if(addContent.value !== ''){
var li = document.createElement('li')
li.innerText = addContent.value
ul.insertBefore(li,ul.firstChild)
}
})
addEnd.addEventListener('click',function(){
if(addContent.value !== ''){
var li = document.createElement('li')
li.innerText = addContent.value
ul.appendChild(li)
}
})
ul.addEventListener('click',function(e){
if(e.target.nodeName.toLowerCase() === 'li'){
console.log(e.target.innerText)
}
})
</script>
</body>
</html>
onlick與addEventListener的區(qū)別声搁?
結(jié)論:
1.onclick事件在同一時(shí)間只能指向唯一對象
2.addEventListener給一個(gè)事件注冊多個(gè)listener
3.addEventListener對任何DOM都是有效的黑竞,而onclick僅限于HTML
4.addEventListener可以控制listener的觸發(fā)階段,(捕獲/冒泡)疏旨。對于多個(gè)相同的事件處理器很魂,不會重復(fù)觸發(fā),不需要手動使用removeEventListener清除
5.IE9使用attachEvent和detachEvent