事件流
1、冒泡型(从内往外依次触发)
从最特定的目标向最不特定的目标(document对象)依次触发事件,也就是事件从下向上进行响应,这个过程被称为冒泡
示例 文档包含5层div元素,为它们定义相同的click事件,同时为每层div标签定义不同的类名。当单击div标签时,设计当前对象边框显示为红色虚线,同时抓取当前标签的类名,以此识别每个标签的响应顺序
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
div {
margin: 20px;
border: 1px solid blue;
font-size: 18px;
}
</style>
<script type="text/javascript">
function bubble() {
var div = document.getElementsByTagName("div")
var show = document.getElementById("show")
for (var i = 0; i < div.length; i++) {
//遍历div元素
div[i].onclick = (function(i) {
//为每个div元素绑定单击事件
return function() {
div[i].style.border = '1px dashed red'
show.innerHTML += div[i].className + "->"
}
})(i)
}
}
window.onload = bubble;
</script>
</head>
<body>
<div class="div-1">div-1
<div class="div-2">div-2
<div class="div-3">div-3
<div class="div-4">div-4
<div class="div-5">div-5
</div>
</div>
</div>
</div>
</div>
<p id="show"></p>
</body>
</html>
阻止事件冒泡
return function(event) {
div[i].style.border = '1px dashed red'
show.innerHTML += div[i].className + "->"
event.stopPropagation()
}
上述JavaScript代码等价于(jQuery代码)
$(function() {
$('div').click(function() {
$(this).css('border', '1px dashed red')
$('#show')[0] += $(this)[0].className
//return false; //阻止事件冒泡
})
})
2、捕获型(从外往内依次触发)
事件从最不特定的目标(document对象)开始被触发,最后到最特定目标,也就是事件从上往下进行响应
示例 修改上述示例,使用addEventListener()方法为5个div元素注册click事件,在注册事件时定义响应类型为捕获型事件,即设置第3个参数为true
for (var i = 0; i < div.length; i++) {
//遍历div元素
div[i].addEventListener('click', (function(i) {
return function() {
div[i].style.border = '1px dashed red'
show.innerHTML += div[i].className + "->"
}
})(i), true)
}
3、混合型
w3c的DOM事件模型支持捕获和冒泡型两种事件流,但是捕获事件流先发生,然后才发生冒泡型事件流。两种事件流触及DOM中所有层级对象,从document对象开始,最后返回document对象结束
绑定事件
<body>
//静态绑定
<button id="btn" onclick="alert('静态绑定')">按钮</button>
<script type="text/javascript">
//动态绑定
var btn = document.getElementById("btn")
/* btn.onclick = function() {
console.log("动态绑定")
} */
</script>
</body>
注册事件与销毁事件
在DOM模型中,通过调用对象的addEventListener()方法注册事件
element.addEventListener(String type,Function listener,boolean useCapture)
type:注册事件的类型名。事件类型与事件属性不同,事件类型名没有on前缀
listener:监听函数,即事件处理函数。在指定类型的事件发生时将调用该函数。在调用这个函数时,默认传递给他的唯一参数是event对象
useCapture:是一个布尔值。如果为true,则指定的事件处理函数将在事件传播的捕获阶段触发;如果为false,则事件处理函数在冒泡阶段触发
在DOM模型中,通过调用对象的removeEventListener()方法可用从指定对象中删除已经注册的事件处理函数
element.removeEventListener(String type,Function listener,boolean useCapture)
示例
<button type="button" id="a">点击</button>
<button type="button" id="b">删除</button>
<script type="text/javascript">
var a = document.getElementById('a')
var b = document.getElementById('b')
function ok() {
alert("欢迎光临!")
}
function remove_event() {
a.removeEventListener('click', ok, false)
}
a.addEventListener('click', ok, false)
b.addEventListener('click', remove_event, false)
</script>
removeElementListener()方法只能删除addEventListener()方法注册的事件。如果直接使用onclick等直接写在元素上的事件,将无法使用removeElementListener()方法删除
event对象
event对象由事件自动创建,代表事件的状态,如事件发生的源节点、键盘按键的响应状态、鼠标指针的移动位置、鼠标按键的响应状态等。event对象的属性提供了有关事件的细节,其方法可以控制事件的传播
事件委托
事件委托,也称为事件托管,就是把目标节点的事件绑定到祖先节点上(原理:事件传播过程中,逐层冒泡总能被祖先节点捕获)
优点:优化代码。提升运行性能,防止在动态添加或删除节点的过程中注册的事件丢失
<ul id='list'>
<li>列表项目1</li>
<li>列表项目2</li>
<li>列表项目3</li>
</ul>
<script type="text/javascript">
var list=document.getElementById("list")
list.onclick=function(event){
console.log(event.target.innerText)
}
</script>
关键点:
1、事件绑定在祖先元素上
2、event.target:返回事件的目标节点(触发该事件的节点),不能使用this(代替的是ul,而不是某一个li)