事件流:描述的是在页面中接收事件的顺序
事件冒泡:由最具体的元素接收,然后逐级向上传播至最不具体的元素的节点
事件捕获:最不具体的节点先接收事件,而最具体的几点应该是最后接收事件
例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js事件</title>
</head>
<body>
<div id="div">
<button id="btn1">按钮</button>
</div>
</body>
</html>
- 事件冒泡时:button接收 —–> div接收 —–> document接收
- 事件捕获时:document接收 —–> div接收 —–> button接收
事件冒泡使用的最多,目前的浏览器也都支持事件冒泡
事件处理
HTML事件处理:直接添加到HTML结构中
DOM 0级事件处理:把一个函数赋值给一个事件处理程序属性
DOM 2级事件处理:addEventListener() removeEventListener()
IE事件处理:attachEvent() detachEvent()
HTML事件处理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js事件</title>
</head>
<body>
<div id="div">
<button id="btn1" οnclick="demo()">按钮</button>
</div>
<script>
function demo(){
alert("hello,html事件处理");
}
</script>
</body>
</html>
缺点:修改一处代码则需要修改两处。例如把js中的函数名demo改了,则html文档里的button也需要修改。代码很多时会很麻烦。
DOM 0级事件处理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js事件</title>
</head>
<body>
<div id="div">
<button id="btn">按钮</button>
</div>
<script>
var btn = document.getElementById("btn");
btn.onclick = function () {
alert("hello, DOM 0级事件处理程序");
};
// btn.onclick = null; // 清除当前事件
</script>
</body>
</html>
- 优点:改动js中的函数时 不用改变HTML文档(中的button按钮)
- 缺点:有多个事件时,只会显示最后一个,前面的会被覆盖
例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js事件</title>
</head>
<body>
<div id="div">
<button id="btn">按钮</button>
</div>
<script>
var btn = document.getElementById("btn");
btn.onclick = function (){ alert("hello,DOM 0级事件处理程序1")};
//btn.onclick = null;//清除当前事件
btn.onclick = function (){ alert("hello,DOM 0级事件处理程序2")};
btn.onclick = function (){ alert("hello,DOM 0级事件处理程序3")};
</script>
</body>
</html>
只能显示第三个,前两个事件都被覆盖了
DOM 2级事件处理
addEventListener(EventName, Callball, Boolean) // 添加事件 [false事件冒泡 true事件捕获]
removeEventListener() // 移除事件
- 添加事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js事件</title>
</head>
<body>
<div id="div">
<button id="btn">按钮</button>
</div>
<script>
var btn = document.getElementById("btn");
btn.addEventListener("click", demo1);
btn.addEventListener("click", demo2);
btn.addEventListener("click", demo3);
function demo1() {
alert("DOM 2级事件处理程序 1");
}
function demo2() {
alert("DOM 2级事件处理程序 2");
}
function demo3() {
alert("DOM 2级事件处理程序 3");
}
</script>
</body>
</html>
三个事件都会显示出来 ,并不会出现覆盖
- 移除事件
<script>
var btn = document.getElementById("btn");
btn.addEventListener("click", demo1);
btn.addEventListener("click", demo2);
btn.addEventListener("click", demo3);
function demo1() {
alert("DOM 2级事件处理程序 1");
}
function demo2() {
alert("DOM 2级事件处理程序 2");
}
function demo3() {
alert("DOM 2级事件处理程序 3");
}
btn.removeEventListener("click",demo2);
</script>
事件2被移除
IE事件处理
attachEvent() // 添加事件
detachEvent() // 移除事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js事件</title>
</head>
<body>
<div id="div">
<button id="btn">按钮</button>
</div>
<script>
var btn = document.getElementById("btn");
if (btn.addEventListener) {
btn.addEventListener("click", demo);
}
else if (btn.attachEvent) {
btn.attachEvent("onclick”, demo);
}
else {
btn.onclick = demo();
}
function demo(){
alert("hello");
}
</script>
</body>
</html>
如果支持addEventListener,进行DOM 2级操作
支持attachEvent,进行IE操作
否则进行DOM 0级操作
事件对象:在触发DOM事件时都会产生一个对象
属性
type 获取事件类型
target 获取事目标
事件属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js事件</title>
</head>
<body>
<div id="div">
<button id="btn">按钮</button>
</div>
<script>
document.getElementById("btn").addEventListener("click", showType);
function showType(event) {
alert(event.type);
// alert(event.target);
}
</script>
</body>
</html>
结果:点击按钮弹出事件类型“click”
将 alert(event.type)
注释,alert(event.target)
取消注释,点击按钮弹出事件对象 [object HTMLButtonElement]
,即HTML中的button元素
方法
stopPropagation() // 阻止事件冒泡
preventDefault() // 阻止事件默认行为
事件冒泡
<div id="div">
<button id="btn">按钮</button>
</div>
<script>
document.getElementById("btn").addEventListener("click", showType);
document.getElementById("div").addEventListener("click", showDiv);
function showType(event) {
alert(event.type);
}
function showDiv(){
alert("div");
}
</script>
结果:点击按钮先后弹出“click”,“div”
解释:只点击了button,但是包含button的div也执行了,这属于事件冒泡,事件逐级向上传递,传给了div,有时并不需要事件冒泡,可以通过stopPropagation()
阻止事件冒泡
<div id="div">
<button id="btn">按钮</button>
</div>
<script>
document.getElementById("btn").addEventListener("click", showType);
document.getElementById("div").addEventListener("click", showDiv);
function showType(event) {
alert(event.type);
event.stopPropagation();
}
function showDiv(){
alert("div");
}
</script>
阻止事件默认行为
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js事件</title>
</head>
<body>
<div id="div">
<button id="btn">按钮</button>
<a href="http://www.google.com" id="aid">阻止事件默认行为</a>
</div>
<script>
document.getElementById("btn").addEventListener("click", showType);
document.getElementById("div").addEventListener("click", showDiv);
document.getElementById("aid").addEventListener("click", showA);
function showType(event) {
alert(event.type);
event.stopPropagation();
}
function showDiv() {
alert("div");
}
function showA(event) {
event.stopPropagation(); //阻止事件冒泡
event.preventDefault(); //阻止事件的默认行为
}
</script>
</body>
</html>
a标签的默认属性是跳转到相应链接,不想点击链接跳转到相应页面时,使用event.preventDefault()
阻止a标签的跳转