#hello,JS:10 -01事件(流)和事件处理程序
前言:
最近,很多事情的时间交叉点汇集到一起,时间明显越来越少了。因为要学做项目了,写博客的记录已经赶不上课程的学习进度,记录知识在博客真的是一个耗费时间和精力的事情啊,这其中还要查资料、弄懂知识点,而且也到了再一次梳理知识集中问老师的时候。赶着时间学习,会有一种赶着你跑的冲劲,加油吧。
一、事件
dom操作,可以用JS在页面上操作元素。不过dom操作需要一个时机,即跟用户交互时,什么时候才能改变这个dom结构,那么此时就用到了事件。
用户在浏览器上的任何操作,都可能触发一个事件,如鼠标移动。滚动页面、点击、甚至鼠标放在页面上的某处等任何的页面操作都会触发一个事件。
二、事件流
事件是如何产生和如何传播
假设事件不传播,无任何事件传播机制,点到什么是什么。那么,当我们点击整个页面的dom,事件却不传播,那页面中的某层结构怎么知道点击了该事件,那又如何去触发事件?
1、事件冒泡模型
元素先监听到这个事件,往外传播
image
2、事件捕获模型
document最先监听到这个事件
image
3、DOM事件流
先捕获,再冒泡
image
允许在某些地方监听事件,假设在某个元素两阶段都绑定一个事件监听器,看你是决定在左边捕获阶段监听,还是右边冒泡阶段监听,哪一边有响应,哪一边事件就被触发。即可以在任一阶段、任意时机监听事件
三、事件的使用方式
1、事件处理程序
也叫事件侦听器。当用户点击(或当某个事件触发的时候),我们所要做的事情。
2、如何绑定事件处理程序?
JavaScript指定事件处理程序
(1)对一个元素绑定一个事件函数:
语法:
<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>
函数什么时候执行?看此例子:http://js.jirengu.com/ponaz/2/edit
当用户点击触发事件时,就会将该事件的对应执行放进任务队列里,此时这个事件函数才会去被执行。由此可以明白两件事:
- 绑定这个函数事件则是同步
- 点击、执行函数事件的操作是异步
(2)对一个元素绑定多个事件函数
看下面这个例子:https://user-gold-cdn.xitu.io/2018/8/13/165314721529faef
<!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>
image
总结: 这个时候,添加了#02事件函数,并点击按钮click me,发事件函数,输出'hello world',直接覆盖#01事件函数的值。
DOM2事件处理程序(实现对一个元素绑定多个事件)
(1)dom作为事件处理的一个基本标准,dom2级事件为dom事件的升级。
(2)DOM2级事件定义用于处理指定和删除事件处理程序的操作:
- addEventListener
- removeEventListener
(3)所有的DOM节点都包含这两个方法,并且它们都接受三个参数:
A、事件类型
B、事件处理方法
C、布尔参数,如果是true表示在捕获阶段调用事件处理程序,如果是false,则是在事件冒泡阶段处理
(4)绑定事件方法实例演示:
addEventListener 绑定事件(直接执行一个函数)
<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>
例子:http://js.jirengu.com/lajoy/1/edit?js,console,output
总结:
这里并不是给变量添加一个值,而是通过执行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
<!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时,在控制台上打印出事件,事件内都是一些对象(带有属性和值),可以从这堆属性中观察到一些重要的参考(只是部分例举),如:
altKey:false //表示在点击事件的时候,没有点alt键
bubbles:true //表示这个事件是冒泡
clientX:39
clientY:18 //表示它的一个位置
toElement:button#btn //说明当前传递的元素
这里可以通过(e.target)看一看到底点击了哪个元素,并不是我们通常意义下看到的例子中的当前元素btn,现在一般来说,绑定一个事件可以使用以下几个方法(续上面的例子):
<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解绑事件,不能使用匿名函数(无法获知要移除哪一个),正确如:
<script type="text/javascript">
var btnClick = document.getElementById('btnClick');
var handler=function() {
alert(this.id);
}
btnClick.removeEventListener('click', handler, false);
</script>
(6)事件整体实例展示
A、冒泡阶段·实例展示
<!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>
默认情况下(无传进的参数),事件绑定是呈现冒泡阶段,执行结果展示:
image
执行的过程事实上是,点击这个事件的时候,一开始便是从container——box——hello,返回时,为冒泡阶段,从hello——box——container,绑定了事件,分别有了响应控制台分别打印出:
"target click..."
"box click..."
"container click..."
这一过程就像是从下到上的冒泡过程,冒泡过程中到哪个事件元素,触发,响应,则会执行对应事件函数
B、事件捕获阶段·实例展示
//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>
image
捕获阶段,点击事件hello,结果显示在刚进去的时候就绑定了事件,所以一开始事件元素就监听到,那么事件触发响应的过程就是hello——box——container,结果为:
"container click..."
"box click..."
"target click..."
C、事件传播整体机制原理和实践·实例展示
//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>
如图所示:结果输出,说明是先进行捕获事件触发、响应,再到冒泡事件触发、响应,先进后出:
image
【不常用】HTML内联方式——onclick ,当用户点击的时候的事件
<input type="button" value="Click Here" onclick="alert('Clicked!');" />