hello,JS:10-01事件(流)和事件处理程序

前言:

最近,很多事情的时间交叉点汇集到一起,时间明显越来越少了。因为要学做项目了,写博客的记录已经赶不上课程的学习进度,记录知识在博客真的是一个耗费时间和精力的事情啊,这其中还要查资料、弄懂知识点,而且也到了再一次梳理知识集中问老师的时候。赶着时间学习,会有一种赶着你跑的冲劲,加油吧。

一、事件

dom操作,可以用JS在页面上操作元素。不过dom操作需要一个时机,即跟用户交互时,什么时候才能改变这个dom结构,那么此时就用到了事件。

用户在浏览器上的任何操作,都可能触发一个事件,如鼠标移动。滚动页面、点击、甚至鼠标放在页面上的某处等任何的页面操作都会触发一个事件。

二、事件流

事件是如何产生和如何传播
假设事件不传播,无任何事件传播机制,点到什么是什么。那么,当我们点击整个页面的dom,事件却不传播,那页面中的某层结构怎么知道点击了该事件,那又如何去触发事件?

1、事件冒泡模型

元素先监听到这个事件,往外传播

2、事件捕获模型

document最先监听到这个事件

3、DOM事件流

先捕获,再冒泡

允许在某些地方监听事件,假设在某个元素两阶段都绑定一个事件监听器,看你是决定在左边捕获阶段监听,还是右边冒泡阶段监听,哪一边有响应,哪一边事件就被触发。即可以在任一阶段、任意时机监听事件

三、事件的使用方式

1、事件处理程序

也叫事件侦听器。当用户点击(或当某个事件触发的时候),我们所要做的事情。

2、如何绑定事件处理程序?

JavaScript指定事件处理程序

(1)对一个元素绑定一个事件函数:
语法:

1
2
3
4
5
6
7
8
<input id="btnClick" type="button" value="Click Here" />

<script type="text/javascript">
var btnClick = document.getElementById('btnClick');//声明一个变量,选择这个元素给它做个赋值,选择这个dom元素
btnClick.onclick = function showMessage() { //元素.事件(),元素绑定一个事件,即onclick,该事件名可以改,如oniput、onfocus等(本身没有执行,只有当事件触触发,即用户交互时,才会被执行)
alert(this.id);//this相当于btnClick这个元素,作为一个占位符存在
};
</script>

函数什么时候执行?看此例子:

当用户点击触发事件时,就会将该事件的对应执行放进任务队列里,此时这个事件函数才会去被执行。由此可以明白两件事:

  • 绑定这个函数事件则是同步
  • 点击、执行函数事件的操作是异步

(2)对一个元素绑定多个事件函数
看下面这个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<button id="btn">click me</button>
</body>
</html>

<script>
var btn = document.querySelector('#btn')
//#事件01
btn.onclick = function(){
console.log(this)
console.log(this.innerText)
}
//#事件02
btn.onclick = function(){
console.log('hello world')
}
</script>


总结: 这个时候,添加了#02事件函数,并点击按钮click me,发事件函数,输出'hello world',直接覆盖#01事件函数的值。

DOM2事件处理程序(实现对一个元素绑定多个事件)

(1)dom作为事件处理的一个基本标准,dom2级事件为dom事件的升级。
(2)DOM2级事件定义用于处理指定和删除事件处理程序的操作:

  • addEventListener
  • removeEventListener

(3)所有的DOM节点都包含这两个方法,并且它们都接受三个参数:

  • A、事件类型
  • B、事件处理方法
  • C、布尔参数,

如果是true表示在捕获阶段调用事件处理程序,如果是false,则是在事件冒泡阶段处理

(4)绑定事件方法实例演示:
addEventListener 绑定事件(直接执行一个函数)

1
2
3
4
5
6
7
8
<input id="btnClick" type="button" value="Click Here" />

<script type="text/javascript">
var btnClick = document.getElementById('btnClick');
btnClick.addEventListener('click', function() {
alert(this.id); //函数里的this代表当前的元素btnClick,所以我们可以通过this.id获取当前元素的id
}, false);
</script>

例子:

总结: 这里并不是给变量添加一个值,而是通过执行addEventListener 这样一个函数,函数可以执行多次,对同样事件可以做多个绑定做不同的事情,也不会产生覆盖。

区别:

1、JavaScript指定事件:btnClick.onclick =functionshowMessage(){alert(this.id);} 为属性添加一个值;DOM2事件处理程序:addEventListener 执行一个函数
2、JavaScript指定事件的事件是:onclick,DOM2事件处理程序的事件是:click
3、DOM2事件处理程序的dom节点最后还可以添加布尔值,表示处于冒泡阶段(false)还是捕获阶段(true)。默认情况下(无传进参数),为冒泡阶段(false)
4、this:alert(this.id)
函数里的this代表当前的元素btnClick,所以我们可以通过this.id获取当前元素的id

思考:
事件到底是什么?此时我们可以通过下面例子来说明事件的一些问题:

例子链接: http://js.jirengu.com/hahid/1/edit?html,js

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<button id="btn">click</button>
</body>
</html>

<script>
//简单的绑定事件,可通过此方法进行绑定
var btn = document.querySelector('#btn')
btn.onclick = function (e){
console.log(e)
}
//通过这个函数可以用来查看这个事件。可以在里面传一个参数e
//或者采用另一种绑定事件的方法:
btn.addEventListener('click',function(e){
console.log(e)
})
</script>

//注:e,只是一个自定义的参数,可以随意改变参数名

点击click时,在控制台上打印出事件,事件内都是一些对象(带有属性和值),可以从这堆属性中观察到一些重要的参考(只是部分例举),如:

1
2
3
4
5
altKey:false  //表示在点击事件的时候,没有点alt键
bubbles:true //表示这个事件是冒泡
clientX:39
clientY:18 //表示它的一个位置
toElement:button#btn //说明当前传递的元素

这里可以通过(e.target)看一看到底点击了哪个元素,并不是我们通常意义下看到的例子中的当前元素btn,现在一般来说,绑定一个事件可以使用以下几个方法(续上面的例子):

1
2
3
4
5
6
7
8
9
10
<script>
var btn = document.querySelector('#btn')
btn.addEventListener('click',function(e){
console.log(this)
//或
console.log(btn)
//或
console.log(e.target)
})
</script>

(5)如何解绑事件(一般情况下不做)
removeEventListener 解绑事件。与addEventListener相对应,通过removeEventListener移除解绑事件,表现为点击时无反应

需要注意的是,removeEventListener解绑事件,不能使用匿名函数(无法获知要移除哪一个),正确如:

1
2
3
4
5
6
7
<script type="text/javascript">
var btnClick = document.getElementById('btnClick');
var handler=function() {
alert(this.id);
}
btnClick.removeEventListener('click', handler, false);
</script>

(6)事件整体实例展示
A、冒泡阶段·实例展示

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<button id="btn">click me</button>

<div class="container">
container
<div class="box">
box
<div class="target">
hello
</div>
</div>
</div>
</body>
</html>

<script>
//选中元素
var container = document.querySelector('.container')

var box = document.querySelector('.box')

var target = document.querySelector('.target')

//绑定事件
container.addEventListener('click', function(){
console.log('container click...')
})

box.addEventListener('click', function(){
console.log('box click...')
})

target.addEventListener('click',function(){
console.log('target click...')
})

</script>

默认情况下(无传进的参数),事件绑定是呈现冒泡阶段,执行结果展示:

执行的过程事实上是,点击这个事件的时候,一开始便是从container——box——hello,返回时,为冒泡阶段,从hello——box——container,绑定了事件,分别有了响应控制台分别打印出:

1
2
3
"target click..."
"box click..."
"container click..."

这一过程就像是从下到上的冒泡过程,冒泡过程中到哪个事件元素,触发,响应,则会执行对应事件函数

B、事件捕获阶段·实例展示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//html同上

<script>
//选中元素
var container = document.querySelector('.container')

var box = document.querySelector('.box')

var target = document.querySelector('.target')

//绑定事件,添加了参数true
container.addEventListener('click', function(){
console.log('container click...')
},true)

box.addEventListener('click', function(){
console.log('box click...')
},true)

target.addEventListener('click',function(){
console.log('target click...')
},true)
<script>

捕获阶段,点击事件hello,结果显示在刚进去的时候就绑定了事件,所以一开始事件元素就监听到,那么事件触发响应的过程就是hello——box——container,结果为:

1
2
3
"container click..."
"box click..."
"target click..."

C、事件传播整体机制原理和实践·实例展示

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
//html同上

<script>
//选中元素
var container = document.querySelector('.container')
var box = document.querySelector('.box')
var target = document.querySelector('.target')

//绑定事件
//捕获事件绑定
container.addEventListener('click', function(){
console.log('container 捕获 click...')
},true)

box.addEventListener('click', function(){
console.log('box 捕获 click...')
},true)

target.addEventListener('click',function(){
console.log('target 捕获 click...')
},true)

//冒泡事件绑定
container.addEventListener('click', function(){
console.log('container 冒泡 click...')
},false)

box.addEventListener('click', function(){
console.log('box 冒泡 click...')
},false)

target.addEventListener('click',function(){
console.log('target 冒泡 click...')
},false)
</script>

如图所示:结果输出,说明是先进行捕获事件触发、响应,再到冒泡事件触发、响应,先进后出:

【不常用】HTML内联方式——onclick ,当用户点击的时候的事件

1
<input type="button" value="Click Here" onclick="alert('Clicked!');" />
-------------本文结束感谢您的阅读-------------