DOM事件

  • 基本概念: DOM事件的级别
  • DOM 事件模型
  • DOM 事件流
  • 描述 DOM 事件捕获的具体流程
  • Event 对象的常见应用
  • 自定义事件

1.基本概念

1
2
3
4
5
6
7
8
9
10
11
12
13
DOM事件类   
DOM1标准制定的时候没有涉及任何和事件相关的东西;

事件级别
DOM0 element.onclick=function(){};
//-->true,false指定冒泡还是捕获

//IE attachEvent
DOM2 element.addEventListener('click',function(){},false);
//-->默认是false(冒泡),true是捕获

//事件类型增加了很多;
DOM3 element.addEventListener('keyup',function(){},false);

2.DOM 事件模型

事件模型过程:

  1. 捕获(从上往下)element.addEventListener('click',function(){},true);

  2. 冒泡(从目标元素往上)element.addEventListener('click',function(){},false);

3.DOM 事件流

浏览器在为当前页面与用户做交互的过程中,比如点击了鼠标左键,这个左键是怎么传到你的页面上,又是怎么响应的。

一个完整的事件流分三个阶段:

1
2
3
1、捕获阶段	   用户点击了鼠标
2、目标阶段 事件通过捕获到达目标元素
3、冒泡阶段 从目标元素上传到window对象后响应给用户看到

4.描述 DOM 事件捕获的具体流程

1
2
3
4
5
6
7
第一个接受事件的对象是window;
取得body标签:document.body;
表示html节点:document.documentElement; // 等于html全部节点(除了!doctype)

// window对象是浏览器提供的, 根据浏览器厂商不同而异
// document对象是W3C标准, 统一的
// window.document可以拿到整个页面所有内容

事件流程图

捕获流程: window–>document–>html标签–>body–>父级元素–子级元素…–>目标元素

冒泡流程:从目标元素一层一层最后到window完成了一次冒泡的流程 ;

5.Event对象的常见应用

  • 1.event.preventDefault(); 阻止默认行为 :绑定事件后会阻止了a元素的链接跳转
  • 2.event.stopPropagation(); 阻止冒泡 :父级元素、子元素都绑定有事件,触发子元素事件的同时也会触发父元素事件
  • 3.event.stoplmmediatePropagation(); 事件响应优先级
1
2
3
一个按钮绑定了两个click事件1和2,想通过优先级的方式,第一个响应函数是a,
第二个响应函数是b,依次注册了a、b两个事件,想让执行a之后完不再执行b了;
a响应函数中加上上面那个代码,就会成功的阻止b执行;
  • 4.event.currentTarget(currentTarget当前绑定事件的对象;指定的是父级元素): 事件委托中会得到 ul 元素
1
把子元素的事件代理都转移到父元素上,只绑定一次事件就可以了。做响应的时候就要区分是哪个元素被触发。
  • 5.event.target(target是当前被点击的元素): 事件委托中会得到 li 元素

6.自定义事件(模拟事件)

1
2
3
4
5
6
7
8
// 创建自定义事件, Event是无法传递参数的
var newEve = new Event('hello');
element.addEventListener('hello', function (e) {
console.log('Im is a custome event');
},false)

// 触发自定义事件newEve
element.dispatchEvent(newEve);

Event对象的不足只能指定事件名,如果想给这个事件加些数据,Event是做不到的;得用CustomEvent对象;

1
2
3
4
5
6
7
8
9
// 1.创建自定义事件, CustomEvent是可以传递参数的
var newEvent = new CustomEvent('build', { detail: elem.dataset.time }); // 点击后拿到值2019-10-01
// <div id="div1" data-time="2019-10-01"></div>

// 2.监听事件
elemment.addEventListener('build', function (e) {}, false);

// 3.发送/触发事件Dispatch the event.
elem.dispatchEvent(event);

总结

举一例子来写出上面的事件DOM讲述的模型。

DOM事件捕获的具体流程以及自定义事件的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<body>
<style>
#btn{
width: 300px;
height: 100px;
background: red;
color: #fff;
text-align: center;
line-height: 100px;
}
</style>
<div id="btn" data-name='hello root'>目标元素</div>
<script>
let eve = document.getElementById('btn');

// 下面为捕获流程, 与代码顺序无关, 改为冒泡则将true改为false即可
window.addEventListener('click', function () {
console.log('window captrue!');
}, true)

document.addEventListener('click', function () {
console.log('docuemnt captrue!');
}, true)

document.documentElement.addEventListener('click', function () {
console.log('HTML captrue!');
}, true)

document.body.addEventListener('click', function () {
console.log('body captrue!');
}, true)

eve.addEventListener('click', function () {
console.log('element captrue!');
}, true)


// 1.使用Event创建自定义事件, Event是无法传递参数的
let newEve1 = new Event('hello');
eve.addEventListener('hello', function (e) {
console.log('Im is a custome event');
},false)

// 触发Event自定义事件newEve1, 业务中一般放在别的事件中响应
eve.dispatchEvent(newEve1);
console.log('================================')


// 2.使用CustomEvent创建自定义事件, CustomEvent是可以传递参数的
var newEvent2 = new CustomEvent('build', { detail: eve.dataset.name }); // 点击后拿到值hello root
// <div id="btn" data-name='hello root'>目标元素</div>

// 监听事件
eve.addEventListener('build', function (e) {
console.log('Im is a custome CustomEvent',e.detail); // 传递参数
}, false);

// 发送/触发事件
eve.dispatchEvent(newEvent2);
</script>
</body>