解释以下概念:事件传播机制、阻止传播、取消默认事件、事件代理。
- 事件传播机制主要有三种:
- 事件冒泡:事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的元素(从小到大)
- 事件捕获:不太具体的节点更早接收事件,而最具体的元素最后接收事件,和事件冒泡相反(从大到小)
- DOM事件流:DOM2 级事件规定事件流包括三个阶段,事件捕获阶段,处于目标阶段,事件冒泡阶段,首先发生的是事件捕获,为截取事件提供机会,然后是实际目标接收事件,最后是冒泡阶段(标准浏览器现在都使用 DOM 事件流,IE 不支持事件流,只支持事件冒泡)
2.阻止传播
- stopPropagation() 取消事件进一步捕获或冒泡
-
取消默认事件
preventDefault() 取消事件默认行为 -
事件代理
通过事件冒泡(或者事件捕获)给父元素添加事件监听,e.target 指向引发触发事件的元素。
写一个 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 捕获阶段 而不再向下出现"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 而不再向上出现"container click in 冒泡阶段"
// e.stopPropagation()
console.log('box click in 冒泡阶段')
},false)
$('.target').addEventListener('click',function(e){
console.log('target click in 冒泡阶段')
},false)
</script>
解释DOM2事件传播机制。
dom2事件传播
dom2事件传播
补全代码,要求:
当点击按钮开头添加时在<li>这里是</li>元素前添加一个新元素,内容为用户输入的非空字符串;当点击结尾添加时在最后一个 li 元素后添加用户输入的非空字符串.
当点击每一个元素li时控制台展示该元素的文本内容。
<ul class="ct">
<li>这里是</li>
<li>饥人谷</li>
<li>任务班</li>
</ul>
<input class="ipt-add-content" placeholder="添加内容"/>
<button id="btn-add-start">开头添加</button>
<button id="btn-add-end">结尾添加</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>任务班</li>
</ul>
<input class="ipt-add-content" placeholder="添加内容"/>
<button id="btn-add-start">开头添加</button>
<button id="btn-add-end">结尾添加</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的区别?
结论:
1.onclick事件在同一时间只能指向唯一对象
2.addEventListener给一个事件注册多个listener
3.addEventListener对任何DOM都是有效的,而onclick仅限于HTML
4.addEventListener可以控制listener的触发阶段,(捕获/冒泡)。对于多个相同的事件处理器,不会重复触发,不需要手动使用removeEventListener清除
5.IE9使用attachEvent和detachEvent