相信大家都知道在web中为元素绑定事件有多种方式,并且都会使用,然而大家可能不理解各种绑定事件方式的本质和所有特性;了解这些本质和特性是很有必要的,因为它能减少我们的代码量和出错率,具体内容如下:(若想更深入地理解JavaScript的各种特性,可以参考另一篇文章:《JavaScript的发现与理解》)
目录
内容
事件处理程序的名字以on
开头,紧接个事件的名字,如:click事件的事件处理程序名字为onclick;
为事件指定处理程序的方式有好几种:
方式1. 对象的事件属性
格式为:
对象.事件属性 = 事件处理函数;
示例:
var btn = document.getElementById("myBtn");
btn.onclick = function(){
//处理事件
}
这种添加方式有以下特点:
- 事件处理程序是作为对象的方法来运行的,所以事件处理程序中this的值是相应的对象;
- 事件处理程序会在事件流的冒泡阶段被调用;
- 通过给对象的事件属性设置null来移除事件;
- 只能同时指定一个事件处理程序;
- 只能把事件处理程序添加到冒泡阶段;
- 使用 对象的事件属性(方式1) 和 HTML的事件标签属性(方式3)这两种方式对 同一个元素 添加的事件处理器,只会最后一次设置的有效;因为 HTML的事件标签属性的方式(方式3) 最终也是通过 对象的事件属性的方式(方式1) 来添加事件处理器的;
- 如果事件处理程序返回假值
return false;
,则会阻止此事件的相关默认操作,即:相当于调用事件对象event的preventDefault()方法;
方式2. 元素的addEventListener方法
这种方式是通过元素的addEventListener方法添加事件处理程序,通过元素的removeEventListener方法移除事件;
所有DOM节点中都包含addEventListener和removeEventListener这2个实例方法,这2个方法的描述如下:
addEventListener方法:
语法:
element.addEventListener(event, function, useCapture)
参数值:
event:必须。字符串,指定事件名。
注意: 不要使用 "on" 前缀。 例如,使用 "click" ,而不是使用 "onclick"。
function:必须。指定要事件触发时执行的函数。
当事件对象会作为第一个参数传入函数。 事件对象的类型取决于特定的事件。例如, "click" 事件属于 MouseEvent(鼠标事件) 对象。
useCapture:可选。布尔值,指定事件是否在捕获或冒泡阶段执行。true - 事件句柄在捕获阶段执行
false- false- 默认。事件句柄在冒泡阶段执行;
示例:
var btn = document.getElementById(“myBtn”);
btn.addEventListener("click", function(){
document.getElementById("demo").innerHTML = "Hello World";
});
removeEventListener方法:
语法:
element.removeEventListener(event, function, useCapture)
参数值:
event:必须。要移除的事件名称。
注意: 不要使用 "on" 前缀。 例如,使用 "click" ,而不是使用 "onclick"。
function:必须。指定要移除的函数。
useCapture:可选。布尔值,可选。布尔值,指定移除事件句柄的阶段。
true - 在捕获阶段移除事件句柄;
false- 默认。在冒泡阶段移除事件句柄;
注意: 如果添加两次事件句柄,一次在捕获阶段,一次在冒泡阶段,你必须单独移除该事件。
示例:
// 向 <div> 元素添加事件句柄
document.getElementById("myDIV").addEventListener("mousemove", myFunction);
// 移除 <div> 元素的事件句柄
document.getElementById("myDIV").removeEventListener("mousemove", myFunction);
这种添加方式有以下特点:
- 可以添加多个处理事件;
- 通过addEventListener添加的事件处理程序,必须通过removeEventListener才能移除;
- 即可以把事件处理程序添加到捕获阶段,又可以添加到冒泡阶段;
- 事件处理程序中this的值是被添加的元素对象;
- 不能通过事件处理程序返回假值
return false;
来会阻止此事件的相关默认操作;
方式3. HTML的事件标签属性
格式为:
<标签名 事件处理程序名="JavaScript代码">
通过这种方式指定的事件处理代码(相应事件处理程序的标签属性(简称:事件标签属性)的值,如:“JavaScript代码”)会被放在一个函数环境中去执行;具体实现机制如下:
通过事件的标签属性指定事件的实现要机制:
- 浏览器会为相应事件动态地创建一个函数作为相应事件的事件处理函数,并把该函数通过对象的事件属性的方式设置给了当前元素dom对象上对应的事件处理器属性上,该函数如下:
dom对象.事件属性 = function (event) { with (document){ with (this){ //元素的事件标签属性的值会在这里被当作JavaScript代码来执行; eval(事件标签属性的值); } } }
- 这个动态创建的事件处理函数中有一个入参,名收
event
,用来接收事件对象;- 事件标签属性的值会被当作JavaScript代码在这个动态创建的事件处理程序中运行:
- 这个动态创建的事件处理函数内部使用
with
将document
和this
对象扩展了成当前的作用域对象,所以document
和this
的所有属性都可以在当前作用域里直接通过属性名字作为变量来直接访问;
通过这个实现机制,可知:
通过事件的标签属性指定事件的方式有以下特点:
- 事件标签属性的值会被当作JavaScript代码在这个动态创建的事件处理程序中运行;
- 使用 对象的事件属性(方式1) 和 HTML的事件标签属性(方式3)这两种方式对 同一个元素 添加的事件处理器,只会最后一次设置的有效;因为 HTML的事件标签属性的方式(方式3) 最终也是通过 对象的事件属性的方式(方式1) 来添加事件处理器的;
- 这个动态创建的事件处理函数中的tihs值是事件的目标元素;事件标签属性的JavaScript代码中被调用的函数的this值是 window 对象;
- 在事件标签属性的值的JavaScript代码中,可以直接访问 保存事件对象的变量
event
、绑定当前事件的dom元素this
,也可以通过document
对象 和 绑定当前事件的dom对象 的任意属性名字作为变量名来直接访问;如:<input onclick="clickHandler(event,this,cookie,value)">
,其中cookie
是document
对象的属性,value
是 input元素的Dom对象的属性;- 只能把事件处理程序添加到冒泡阶段;
- 在事件标签属性的值中可以通过返回假值
return false;
来阻止此事件的相关默认操作,即:相当于调用事件对象event的preventDefault()方法;