事件机制
事件是由三部分组成
事件源 事件类型 事件处理程序 我们也称为事件三要素 1.事件源:事件被触发的对象 -->按钮对象 2.事件类型:如何触发?触发什么事件?例如鼠标点击,键盘按下等… 3.事件处理程序:通过一个函数赋值的方式
执行事件的步骤
1.获取事件源
2.注册事件(绑定事件)
3.采用函数赋值形式添加事件处理程序
事件传播分成三个阶段:
捕获阶段:从window对象传导到目标节点(上层传到底层)称为“捕获阶段”(capture phase),捕获阶段不会响应任何事件;
目标阶段:在目标节点上触发,称为“目标阶段”
冒泡阶段:从目标节点传导回window对象(从底层传回上层),称为“冒泡阶段”(bubbling phase)。事件代理即是利用事件冒泡的机制把里层所需要响应的事件绑定到外层;
1.1.事件冒泡(IE事件流)
IE 事件流被称为事件冒泡,这是因为事件被定义为从最具体的元素(文档树中最深的节点)开始触发,然后向上传播至没有那么具体的元素(文档)。
click事件首先在 被点击元素上发生,然后逐级向上父级元素传播。这就是事件冒泡。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
color: white;
font-size: 20px;
}
#outer{
width: 300px;
height: 300px;
background-color: red;
}
#center{
width: 200px;
height: 200px;
background-color: blue;
}
#inner{
width: 100px;
height: 100px;
background-color: green;
}
</style>
</head>
<body>
<div id="outer">outer
<div id="center">center
<div id="inner">inner</div>
</div>
</div>
<script>
var inner = document.getElementById('inner');
var center = document.getElementById('center');
var outer = document.getElementById('outer');
// 当我们只有一个inner点击方法的时候 我们发现想要实现的效果和我们预期的一样
inner.onclick = function () {
console.log('我是inner点击的');
}
// 但是当我们给inner的父元素和祖先元素也添加点击事件时 一点击inner 所有祖先元素的事件都会被触发,这就是事件冒泡现象
center.onclick = function () {
console.log('我是center点击的');
}
outer.onclick = function () {
console.log('我是outer点击的');
}
</script>
</body>
</html>
阻止事件冒泡有两种方式
1,在要要触发的点击事件函数中 写 window.event.cancelBubble = true; 这种方法 IE 和谷歌 支持,而火狐不支持
2,在事件处理函数中传入一个对象参数, 在函数中添加 对象参数.stopPropagation();
2.事件处理程序
事件意味着用户或浏览器执行的某种动作。比如,单击(click)、加载(load)、鼠标悬停(mouseover)。为响应事件而调用的函数被称为事件处理程序(或事件监听器)。事件处理程序的名字以"on"开头,因此 click 事件的处理程序叫作 onclick,而 load 事件的处理程序叫作 onload。有很多方式可以指定事件处理程序。
HTML 事件处理程序
特定元素支持的每个事件都可以使用事件处理程序的名字以 HTML 属性的形式来指定。此时属性的值必须是能够执行的 JavaScript 代码。例如,要在按钮被点击时执行某些 JavaScript 代码,可以使用以下 HTML 属性:
在 HTML 中定义的事件处理程序可以包含精确的动作指令,也可以调用在页面其他地方定义的方法。
<!-- 需要加() -->
<button οnclick="showMsg()">点我啊</button>
<script>
function showMsg() {
console.log('Hello Wolrd!');
}
</script>
DOM2 事件处理程序
addEventListener()添加的事件处理程序 ,而且可以为同一个事件添加多个事件处理程序
例如:
<button id='btn'>点我啊</button>
<script>
var btn = document.getElementById("btn");
btn.addEventListener("click", function () {
console.log('我被点击了');
}, false);
btn.addEventListener("click", function () {
console.log(this.id); // btn
});
</script>
通过 addEventListener()添加的事件处理程序只能使用 removeEventListener()并传入与添加时同样的参数来移除。这意味着使用 addEventListener()添加的匿名函数无法移除,
如下面的例子所示:
<button id="btn"> 点击</button>
<script>
//调用 addEventListener()和 removeEventListener()时传入的是同一个匿名函数时,
//将无法移除addEventListener()添加的事件处理程序
b1.addEventListener('click', function () {
console.log('hello world');
})
b1.removeEventListener('click', function () {
console.log('hello world');
})
</script>
3.事件对象
阻止默认事件发生
preventDefault()方法用于阻止特定事件的默认动作。比如,链接的默认行为就是在被单击时导航到 href 属性指定的 URL或是修改表单提交的默认事件。如果想阻止这些行为,可以在 onclick 事件处理程序中取消,如下面的例子所示:
<a href="http://www.baidu.com">跳转</a>
<form action="./1-HTML事件处理程序.html">
<button id="btn">提交按钮</button>
</form>
<script>
var a = document.getElementsByTagName('a')[0];
var btn = document.getElementById('btn');
a.onclick = function (event) {
// alert(1);
// 阻止事件默认行为
event.preventDefault();
}
btn.onclick = function (event) {
// 阻止事件默认行为
event.preventDefault();
}
</script>
4.事件委托
基本概念
事件代理(Event Delegation),又称之为事件委托。是JavaScript中常用绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定在子元素的响应事件(click、keydown......)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。
如果对页面中所有需要使用 onclick 事件处理程序的元素都如法炮制,结果就会出现大片雷同的只为指定事件处理程序的代码。使用事件委托,只要给所有元素共同的祖先节点添加一个事件处理程序,就可以解决问题。
比如:
<ul id="myLinks">
<li id="li1">somewhere</li>
<li id="li2">something</li>
<li id="li3">say HI</li>
</ul>
<script>
// 事件委托 给所有节点共同的祖先元素添加事件
var list = document.getElementById('myLinks');
list.addEventListener('click',function (event) {
console.log(event.target.id);//点击那个文本target就指向那个文本对应的id
var target = event.target;//event.target 属性:返回哪个 DOM 元素触发了事件
switch (target.id) {
case 'li1':
target.innerHTML = 'SuZhou'
break;
case 'li2':
target.innerHTML = 'Coding'
break;
case 'li3':
target.innerHTML = 'Hi'
break;
default:
break;
}
})
</script>