JS DOM基础 事件概述 事件流 事件处理方法 添加监听器 事件类型 事件对象 事件委托
一、事件概述
事件是什么?
在我们的生活中,都会接触到事件这样一个概念,它通常通过描述发生这件事的时间、地点、人物,发生了什么来进行概括。
同样的在javascript也有这样的一个的东西------事件。
页面上发生的事件:鼠标移动、点击、滚动等等。
事件描述了页面上发生的事情,通常它有以下三个要素组成:
事件源:触发事件的元素
事件类型:事件的触发方式(例如鼠标点击或键盘点击)
事件处理程序(事件监听器):事件触发后要执行的代码(函数形式)
Javascript 使我们可以动态的去操作一个页面。当我们在与浏览器交互的时候,浏览器就会触发各种事件。
比如我们打开某一个网页的时候,浏览器需要加载完成这个网页,就会触发一个加载事件;当我们点击页面中的某一个“地方”,浏览器就会在那个“地方”触发一个点击事件。
二、事件流
什么是事件流?
DOM(文档对象模型)结构是一个树型结构,当一个HTML元素产生一个事件时,该事件会在元素结点与根结点之间的路径传播,路径所经过的结点都会收到该事件,这个传播过程、这种问题的处理方式可以称之为事件流即事件的传播机制。对于事件流IE跟FF有不同的解释。
IE下的解决方案称之为:冒泡型事件,从里向外
而FF下称之为:捕获型事件,从外向里。
冒泡型事件是从低而上的触发机制,而捕获型事件则是从上到下的触发机制。
DOM同时支持这两种事件模型:捕获型事件和冒泡型事件,并且把事件流分为了三个阶段:
事件捕获阶段,处于目标阶段,事件冒泡阶段。
处于目标阶段时(中间阶段)的事件触发顺序,和事件的声明顺序有关,先声明的先触发,一般不怎么关注前两个阶段,默认冒泡阶段dom0。
三、事件处理方法
事件的绑定、添加监听器
要使用事件,首先我们需要绑定事件。
DOM0级提供了两种事件绑定方案:
事件绑定在html标签上:
<input type="button" onclick="doit()" value="test"> //onclick="doit()",内嵌式,鼠标点击,调用函数 doit
<script> function doit() {alert("html绑定");} </script>
注:将js与html合并在一起,没有实现分离,违背了结构、样式、行为分离的要求,不推荐。
但有时候这样子很方便或者需要,也可以用。
函数绑定:
<input id='inputBtn' type="button" value="test"> <script> let btn = document.getElementById('inputBtn’); btn.onclick = function () {alert('函数绑定');} //可以通过btn.onclick = null;的方式 删除
</script>
注:兼容性很好,但是只能绑定一个监听处理函数。
DOM2级新增了一种事件绑定方案:
通过方法addEventListener():
<input id='inputBtn' type="button" value="test"> <script> let btn = document.getElementById('inputBtn’); btn.addEventListener('click', function () {alert('addEventListener方法');}); </script>
注:兼容性相对稍差,但是可以绑定多个事件函数。
-
使用
addEventListener(type, listener, useCapture)
来注册事件的时候,第三个参数默认为false
,代表事件捕获方式为冒泡 -
使用
.stopPropagation()
可以阻断事件的传播,当为事件捕获时,阻断事件向下传播,当为事件冒泡时,阻断事件向上传播 -
.preventDefault()
是用来阻止DOM
元素默认的事件的,比如a标签
的跳转动作,表单button
的提交动作,与事件传播没关系
事件的移除
DOM0级:
targetElement.onclick = null;
DOM2级:
targetElement.removeEventListener(type, listener);
注意:事件函数listener需要保存才可以移除,因为需要传入该函数的引用
let a,b,c; btn.addEventListener('click',a= function () {alert('addEventListener方法1');}); btn.addEventListener('click',b= function () {alert('addEventListener方法2');}); btn.addEventListener('click',c= function () {alert('addEventListener方法3');}); btn.removeEventListencer("click",a);
四、事件类型
页面事件
onload 一张页面或一幅图像完成加载时触发的事件
onresize 窗口或框架被重新调整大小时触发的事件。
onscroll 当文档被滚动时触发的事件
鼠标事件
onclick 当鼠标点击某个元素时触发的事件
ondblclick 当鼠标双击某个元素时触发的事件
onmousedown 当鼠标按钮被按下时触发的事件
onmouseup 当鼠标按键被松开时触发的事件
onmousemove 当鼠标在鼠标事件某个元素上移动时触发的事件
onmouseenter 当鼠标指针移动到元素上时触发的事件
onmouseleave 当鼠标指针移出元素时触发的事件
onmouseover 鼠标指针移动到元素上时触发的事件
onmouseout 当鼠标指针移出元素时触发的事件
注意1:事件mousemove会在满足条件的情况下不断触发;
注意2: onmouseenter和onmouseleave在进入元素时触发,其他时候不会触发;
onmouseover和onmouseout不光会在进入元素时触发,在元素的子元素上也会触发。
键盘事件
onkeydown 当键盘按键被按下时触发的事件。
onkeypress 当键盘按键被按下并松开时触发的事件。
onkeyup 当键盘按键被松开时触发的事件。
注意1:事件触发顺序是down,press,up;
注意2:其中down和up任意的按键都能触发,press只有字符输入时会触发;
也就是说,shift,delete这些特殊按键不会触发press事件;
同时down和up并不能知道按下键的具体内容(比如大小写),而press就关注内容。
表单事件
focus 获得焦点时触发
blur 失去焦点时触发
reset 重置表单时触发
submit 提交表单时触发
change input框失去焦点,判断value是否改变,改变时触发
input 输入内容时,value改变了就触发
五、事件对象
事件中的详细信息,事件内部的一些处理方法。
IE 8 及之前版本 IE 浏览器:event 事件对象被提供在window对象中。
所以有了兼容性的写法:
<input type="button" value="点击" id="clickBtn"> <script> clickBtn.onclick = function (event) { let e = event || window.event; } </script>
事件目标
event 事件对象提供了target属性用于获取触发事件的目标元素(标签)。
<p id="para"> 我是一个p标签 </p> <script> para.onclick = function(event){ console.log( event.target ); } </script>
IE8 及之前版本的 IE 浏览器中同样存在兼容性问题,是srcElement属性,
上面的javaScript代码改写成:
para.onclick = function(event){ let target = event.target || event.srcElement; }
事件目标(事件源)与 this
在事件的处理函数中,可以通过this关键字来指代绑定该事件的标签元素。
para.onclick = function(){ console.log(this == para); //true }
注:绑定事件监听器时,不能使用箭头函数,不然就没有this。
区分this和event.target:
this指绑定监听器的元素节点;
event.target指触发事件的目标元素节点。
事件上与鼠标事件相关的属性
事件对象(event)上提供了一些属性,可以用来获取当鼠标事件发生时鼠标的坐标
clientX 返回当事件被触发时鼠标指针相对于浏览器文档显示区的水平坐标
clientY 返回当事件被触发时鼠标指针相对于浏览器文档显示区的垂直坐标
pageX 返回当事件被触发时鼠标指针相对于 HTML 文档页面的水平坐标
pageY 返回当事件被触发时鼠标指针向对于 HTML 文档页面的垂直坐标
screenX 返回事件发生时鼠标指针相对于屏幕的水平坐标
screenY 返回事件发生时鼠标指针相对于屏幕的垂直坐标
offsetX 返回事件发生时鼠标指针相对于事件源的水平坐标
offsetY 返回事件发生时鼠标指针相对于事件源的垂直坐标
功能键标志属性
ctrlKey altKey
阻止默认行为
有些事件发生有默认行为,有时候不需要它执行,可以阻止:
阻止默认行为:
e.preventDefault(); 或 return false;(只能用于dom0级)
阻止事件流传播:
e.stopPropergation(); 或 e.cancelBubble=true;
六、事件委托
事件代理:将子节点的事件监听器,放置在上级(父亲或祖先)节点上,利用的是事件冒泡原理,实现上级节点代理子节点事件的一种技术。
一般在,子节点很多,多个子节点需要绑定类似的事件函数,或子节点是动态时使用。
可以很大程度上优化节约性能,也能解决节点动态问题。
注:上级节点的选定,要看情况,一般近一点比较好,还要保证必定不是动态节点。
并且因为依赖事件冒泡,所以必须使用 mouseenter、mouseleave(事件会冒泡),mouseover和mouseout事件不会冒泡。