JavaScript 事件

icon13

首先这篇文章不讲述一些事件的用法,例如mousedown,mouseup,keydown等等.
JS事件也随着时间的推移变的越来越多,随着移动设备出现,一些手势事件也出现了.
本文依然不讲这些.而是说明JS中的事件到底是怎么回事,讲述一些原理.

事件分类

一.传统事件

mousedown,mouseup,keydown….

二.DOM事件模型

1.DOM第0级事件模型
2.DOM第2级事件模型

三.IE事件模型
四.jQuery事件模型

DOM第0级事件模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
DOM第0级事件模型 : 在这种事件模型下,事件处理器是通过一个函数直接赋值
给DOM元素的属性来声明的

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div>div element</div>
</body>
<script>
var divElement = document.getElementsByTagName("div");
divElement[0].onclick = function(){
alert("click divElement");
}
</script>

</html>

DOM第2级事件模型概念

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
DOM第2级事件模型概念:事件处理器不是通过元素的属性赋值的,而是通过元素的方法.
每个函数定义有一个名为addEventListener的方法

在说明DOM第2级事件模型之前我们想一下DOM第0级事件模型的缺点:
存储的实行上的函数充当了事件处理器,所以对于任意指定的事件类型,
一个元素每次只能注册一个事件处理器,如果点击元素时执行两件事情
这是不可行的
Element.onclick = function(){
第一件事件
}
Element.onclick = function(){
第二件事件
}
只有第二件事件会被注册.第一件事情将被覆盖.而DOM第2级事件模型完美的解决了这个问题.


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div>div element</div>
</body>
<script>
var divElement = document.getElementsByTagName("div");

divElement[0].addEventListener('click',function(){
alert("once");
},false);
divElement[0].addEventListener('click',function(){
alert("twice");
},false);

//这里的第三的参数false后面我会说明
</script>

</html>

IE事件模型

1
2
IE事件模型:IE没有addEventListener函数
在IE中名字变成了attachEvent('eventName',handler)

jQuery事件模型

1
jQuery事件模型:jQuery有很多关于事件的函数bind(),one(),on(),off(),live()

IE事件模型,jQuery事件模型我一笔带过
先感受一下事件原理性的东西.
接下来引出新的问题

事件传播

一.事件传播的分类

1.事件冒泡
2.事件捕获

二.阻止事件传播

icon12

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
事件冒泡:
在调用目标元素上注册的事件处理函数后,大部分事件会"冒泡"到DOM树根部.
调用目标的父元素的事件处理程序,然后调用在目标的祖父元素上注册的事件处理
程序,一直到Document对象,最后到达Window对象,这一过程称为事件冒泡.
事件捕获:
正好与事件冒泡相反,从window对象都目标元素的的过程。

一般浏览级事件传播默认是事件冒泡,我们可以设置事件传播的方式是冒泡方式,还是捕获方式
上面所讲的addEventListener函数的第三个参数就是选择事件传播的方式,传入true事件
传播方式为事件捕获,传入false事件传播方式为事件冒泡.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="one">
div1
<div id="two">
div2
<div id="three">div3</div>
</div>
</div>
<script>
var os = document.getElementsByTagName("div");
for(var i = 0 ; i < 3 ; i++){
os[i].onclick = function(e){
alert(e.target);
}
}
</script>


现象:
当我们点击div3时会弹出3次's'
当我们点击div2时会弹出2次's'
当我们点击div1时会弹出1次's'
默认为事件冒泡方式传播事件


若想观察事件储波的方向可以这么做.打开控制台结果一目了然
<script>
var os = document.getElementsByTagName("div");
for(var i = 0 ; i < 3 ; i++){
os[i].addEventListener('click',function(){
console.log(this);
e.stopPropagation();
},false);
}
</script>

</html>

阻止事件传播:

1
2
3
4
5
6
7
8
9
10
11
12
13
阻止事件传播:
使用Event.stopPropagation()方法,阻止事件冒泡

修改上面的代码
<script>
var os = document.getElementsByTagName("div");
for(var i = 0 ; i < 3 ; i++){
os[i].addEventListener('click',function(){
console.log(this);
e.stopPropagation();
},false);
}
</script>

JS优化

一个案例:事件冒泡应用

多个li标签绑定点击事件的加速解决方案

1.事件委托概念.JavaScript原生方法实现
2.利用jQuery的on()函数实现

传统for循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
目标:点击li标签是弹出li标签所对应的id值
<ul id="list">
<li id="one">li1</li>
<li id="two">li2</li>
<li id="three">li3</li>
</ul>
<script>
var os = document.getElementsByTagName("li");
for(var i = 0 ; i < os.length ; i++){
os[i].onclick = function(e) {
alert(e.target.id);
};
}

</script>

事件委托方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 事件委托概念:
原本是li标签的点击事件,我们委托给ul标签处理
为什么可以这样做.因为事件时冒泡的点击li标签
事件会冒泡到ul标签上,这是我们没有使用for循环

题外话:
对js进行了优化,不要小看这一个细节,
网页中大量li td tr标签.这样优化
效果的下注的.

<ul id="list">
<li id="one">li1</li>
<li id="two">li2</li>
<li id="three">li3</li>
</ul>
<script>
var os = document.getElementById("list");
os.addEventListener('click',function(e){
alert(e.target.id);
})
</script>

jQuery on()函数
on()用法1,这里看一下
on()用法2,这里看一下

1
2
3
4
5
6
7
8
9
10
11
12
13
选择document对象上的所有element并匹配#list进行click事件绑定,委托在document对象上
<ul id="list">
<li id="one">li1</li>
<li id="two">li2</li>
<li id="three">li3</li>
</ul>
<!-- bootstrap jquery cdn -->
<script src="http://cdn.bootcss.com/jquery/2.1.3/jquery.js"></script>
<script>
$(document).on('click',$("#list"),function(e){
alert(e.target.id)
})
</script>

(完) 写了好几个小时!