事件
事件是什么?
事件处理程序和使用
事件的传播
Event对象
事件代理机制
其他事件
1.事件是什么?
MDN上的解释是这样的:
事件是您在编程时系统内发生的动作或者发生的事情,系统通过它来告诉您在您愿意的情况下您可以以某种方式对它做出回应。例如:如果您在网页上单击一个按钮,您可能想通过显示一个信息框来响应这个动作。
在Web中, 事件在浏览器窗口中被触发并且通常被绑定到窗口内部的特定部分 — 可能是一个元素、一系列元素、被加载到这个窗口的 HTML 代码或者是整个浏览器窗口。举几个可能发生的不同事件:
- 用户在某个元素上点击鼠标或悬停光标。
- 用户在键盘中按下某个按键。
- 用户调整浏览器的大小或者关闭浏览器窗口。
- 一个网页停止加载。
- 提交表单。
- 播放、暂停、关闭视频。
- 发生错误。
简单的说用户在浏览器上的行为一般都会产生事件。
2.事件处理程序和使用
事件处理程序:
我们也称之为时间侦听器(listener),事件就是用户或浏览器自身执行的某种动作。比如click、load、mouseover等,都是事件类型(俗称事件名称),而响应某个事件的方法就叫做事件处理程序或者事件监听器。
也就是我们需要提前定义好某些事件发生了该怎么处理,这个过程叫做绑定事件处理程序。
怎么使用绑定事件处理程序呢?
1)HTML内联方式
<button onclick="alert('hello world')">点击我</button>
这个方法将JS事件的方法内嵌在HTML的标签并且作为属性使用,但是这个做法违反我们提倡的结构,样式和行为的分离,所以一般不是用这种方法。
2)指定事件处理程序(DOM0级)
<button id="btn">点击我</button> var btn = document.querySelector('#btn') btn.onclick = function(){ alert('hello world') }
像这样将一个方法赋值给指定的事件处理程序也成为DOM0级事件处理程序,但是如果重新赋值那么会覆盖之前的方法,所以这方法只能绑定一个事件。
3)addEventListener()和removeEventListener() (DOM2级)
DOM2级提供了一个函数,用于在当前节点或对象上,定义一个特定事件的监听函数。一旦这个事件发生,就会执行监听函数。该方法没有返回值。
该方法接收三个参数:
type
:事件名称,大小写敏感。listener
:监听函数。事件发生时,会调用该监听函数。useCapture
:布尔值,表示监听函数是否在捕获阶段(capture)触发,默认是false冒泡阶段。
<button id="btn">点击我</button> var btn = document.querySelector('#btn') btn.addEventListener('click',function(){ alert('hello world') })
3.事件的传播
事件模型:
- 事件冒泡
- 事件捕获
- DOM事件流
事件冒泡:
IE事件冒泡事件冒泡即事件开始时,由最具体的元素接收(也就是事件发生所在的节点),然后逐级传播到较为不具体的节点。
事件捕获:
事件捕获事件捕获的概念,与事件冒泡正好相反。它认为当某个事件发生时,父元素应该更早接收到事件,具体元素则最后接收到事件。
DOM事件流:
DOM事件流DOM2级事件规定事件流包括三个阶段,事件捕获阶段,处于目标阶段,事件冒泡阶段,首先发生的是事件捕获,为截取事件提供机会,然后是实际目标接收事件,最后是冒泡
4.Event对象
事件发生以后,会产生一个事件对象,作为参数传给监听函数。浏览器原生提供一个Event
对象,所有的事件都是这个对象的实例,或者说继承了Event.prototype
对象。
在触发DOM上的某个事件的时候会产生一个事件对象event,这个对象包含着所有与事件有关的信息,包括产生事件的元素、事件类型等相关信息。所有浏览器都支持event对象,但支持方式不同。
下面说一些事件对象中的常用属性和方法
target 事件的目标元素
var box = document.querySelector('.box') box.onclick = function(e){ console.log(e.target) } // <div class="box"></div>
stopPropagation() 取消事件进一步冒泡或捕获
这里写个DOM事件流的模型代码
<div class="a">我是a <div class="b">我是b <div class="c">我是c</div> </div> </div>
html代码
document.querySelector('.a').addEventListener('click',function(e){ console.log('我是盒子a ,在捕获阶段') },true) document.querySelector('.b').addEventListener('click',function(e){ console.log('我是盒子b ,在捕获阶段') },true) document.querySelector('.c').addEventListener('click',function(e){ console.log('我是盒子c ,在捕获阶段') },true) document.querySelector('.c').addEventListener('click',function(e){ console.log('我是盒子c ,在冒泡阶段') },false) document.querySelector('.b').addEventListener('click',function(e){ console.log('我是盒子b ,在冒泡阶段') },false) document.querySelector('.a').addEventListener('click',function(e){ console.log('我是盒子a ,在冒泡阶段') },false)
JS代码
当我们点击盒子c的输出的结果:
我们可以用stopPropagation方法可以取消进一步冒泡或捕获,这里我们取消盒子c进一步冒泡
document.querySelector('.c').addEventListener('click',function(e){ e.stopPropagation() console.log('我是盒子c ,在冒泡阶段') },false)
点击盒子c再看下输出结果:
事件过程停在盒子c就不会往上继续冒泡了。
prenentDefalut 取消事件默认行为
这个方法可以取消浏览器事件的默认行为,比如可以设置链接跳转的行为
document.querySelector('a').onclick = function(e){ e.preventDefault() }
5.事件代理机制(事件委托)
由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理(delegation)。
6.其他事件
鼠标事件
onmousedown,onmouseup,onclick,ondbclick,wonmousewheel,onmousemove,onmouseover,onmouseout
触摸事件
ontouchstart,ontouchend,ontouchmove
键盘事件
onkeydown,onkeyup,onkeypress
页面相关事件
onload,onmove(浏览器窗口被移动时触发),onresize(浏览器的窗口大小被改变时触发),onscroll(滚动条位置发生变化时触发)