事件是某些动作发生时产生的信号。JavaScript能够感知这些信号,因此能够编写代码来响应这些信号,也就是响应这些事件。而响应某个事件的函数就叫做 事件处理程序(或事件侦听器) 。事件处理程序的名字以 on 开头,所以 click 点击事件的事件处理程序就是 onclick , load 事件的事件处理程序就是 onload 等等。为事件指定处理程序的方法有很多种,下面会一一介绍。
事件处理程序是发生事件时执行的程序,可以将事件处理函数作为HTML标签的一个属性来使用,事件处理程序指定方式的通用格式为:
<html_tag other_attributes eventhandler="javascript program">
例如要在一个按钮上执行某些JavaScript,可以像下面这样写代码:
<input type="button" value="点击" onclick="alert('你点击了按钮')">
当我们点击了这个按钮的时候就会弹出一个确认框。注意,因为 onclick 的值是JavaScript,因此不能在其中使用未经转义的HTML字符,例如: & 、 "" 、 < 和 > 。
在HTML中定义的事件处理程序可以包含要执行的具体代码,也可以调用页面其它地方定义的函数。例如:
<script type="text/javascript"> function showMessage(){ alert("hello world!"); } </script> <input type="button" value="点击" onclick="showMessage()">
上面的例子中,单击按钮就会执行 showMessage() 函数。 showMessage() 函数可以在页面中的一个 <script> 元素中定义,也可以在外部的js文件中定义。事件处理程序中的代码在执行的时候,有权访问全局作用域中的任何代码。
在HTML代码中指定事件处理程序有2个缺点:
1、HTML代码和JavaScript高度耦合,如果要更换事件处理程序需要更换两个地方:HTML代码和JavaScript代码。 2、当HTML代码出现的时候,它上面的事件处理程序可能还没有准备就绪,有可能会引发执行错误。例如:如果事件处理程序指定的JavaScript代码在页面的最底部定义,那么在页面解析到HTML元素的时候,相应的事件处理代码还没有被解析,这时执行HTML元素的事件处理程序就有可能会出现错误。因为在HTML代码中直接指定事件处理程序存在一些缺陷,所以人们转而使用JavaScript来指定事件处理程序。通过JavaScript来指定事件处理程序的方式就是将一个函数赋值给一个事件处理属性。
在DOM0级事件处理程序中,要使用JavaScript来指定事件处理程序,首先需要获取操作对象的引用。每一个元素对象都有自己的事件处理属性,例如 onclick ,将这些属性的值设置为一个函数,就可以指定事件处理程序了。例如:
<input type="button" value="点击" id="btn"> <script type="text/javascript"> var btn = document.getElementById("btn"); btn.onclick = function(){ alert("你点击了按钮"); } </script>
使用DOM0级方法指定的事件处理程序被认为是元素的方法。这时候的事件处理程序是在元素的作用域中运行的,也就是说,在事件处理程序中, this 引用就是这个元素对象。例如:
<input type="button" value="点击" id="btn"> <script type="text/javascript"> var btn = document.getElementById("btn"); btn.onclick = function(){ alert(this.id); //输出“btn” } </script>
我们可以在上事件处理程序中使用 this 关键字来获取元素的所有属性和方法。以这种方式添加的事件处理程序会在的冒泡阶段被处理。例如使用下面的代码可以查看事件冒泡的情况。
<html lang="zh" id="html" class="demo"> <head> <meta charset="UTF-8"> <title>事件冒泡</title> </head> <body id="body" class="demo"> <div id="parent" class="demo"> <button id="child" class="demo">点击一下</button> </div> </body> </html>
执行下面的JavaScript代码,这段代码使用DOM0级事件处理程序,处理程序中首先获取页面中所有的DOM元素,然后对每一个DOM元素进行循环遍历添加鼠标点击事件,最后在控制台中查看事件源和事件目标出现的先后顺序。
window.onload = function(){ var elements = document.querySelectorAll(".demo"); for(var i = 0 ; i < elements.length; i++){ elements[i].onclick = function(event){ var element = elements[i]; //获取事件 event = event?event:window.event; //获取事件发生的目标 target = event.target?event.target:event.srcElement; console.info("事件源:"+target.id+" , "+target.tagName+", 事件对象:"+this.id); } } }
下面是控制台中输出的结果:
从控制台中的输出结果可以看出,由上到下的顺序为child→parent→body→html,说明事件最先发生在按钮(child)上面,然后逐级往上冒泡。
DOM0事件处理程序会产生事件冒泡。如果要取消事件冒泡,可以使用 event.stopPropagation() 方法,但是IE浏览器不支持这个方法,在IE中,取消事件冒泡的方法为: event.cancleBubble = true 。
//取消事件冒泡 event.stopPropagation(); //DOM方法 event.cancleBubble = true; //IE的方法
另外要提的一点是DOM0事件处理程序不支持事件捕获。
我们也可以删除通过DOM0级方法指定的事件处理程序,只要将事件处理程序属性的值设置为 null 即可。
btn.onclick = null;
使用DOM0级事件处理程序最大的问题是事件会被覆盖。来看下面的例子:
<input type="button" value="点击" id="btn"> <script type="text/javascript"> var btn = document.getElementById("btn"); btn.onclick = function(){ console.info("event-one"); } btn.onclick = function(){ console.info("event-two"); } btn.onclick = function(){ console.info("event-three"); } </script>
在上面的代码中,通过按钮的引用对象为按钮添加了3个事件处理函数,那么现在的问题是哪一个事件处理程序会被执行?答案是第三个事件处理程序会被执行,控制台中会输出“event-three”。这是因为 btn.onclick 实际上就像一个指针,在执行第一个事件处理程序时它指向了内存中的一个引用,执行第二个事件处理程序时它又会指向另一个内存的引用,最终会指向第3个事件处理函数的内存引用。
由于DOM0级事件处理程序会产生事件冒泡和事件覆盖等问题,W3C组织制定了“DOM2级事件处理程序”。“DOM2级事件处理程序”定义了2个方法,用于处理指定和删除事件处理程序的操作,这2个方法是: addEventListener 和 removeEventListener 。所有的DOM节点中都包含这两个方法,这些方法接收3个参数:要处理的事件名称、作为事件处理程序的函数和一个布尔值。布尔值参数如果设置为 true ,表示在捕获阶段调用事件处理程序,如果设置为 false ,表示在事件冒泡阶段调用事件处理程序。
如果要在一个按钮上添加DOM2级事件处理程序,可以使用下面的代码:
<input type="button" value="点击" id="btn"> <script type="text/javascript"> var btn = document.getElementById("btn"); btn.addEventListener("click",function(){ alert(this.id); },false); </script>
上面的代码为按钮添加了一个DOM2级事件处理程序,事件名称是 click ,对应DOM0级的 onclick 属性。因为最后一个参数为 false ,所以这个事件会在冒泡阶段被触发。
和DOM0级事件处理程序相同,DOM2级事件处理程序也会依附在元素的作用域中运行。
使用DOM2级事件处理程序就可以避免DOM0级事件处理程序的事件覆盖问题。例如下面的例子:
<input type="button" value="点击" id="btn"> <script type="text/javascript"> var btn = document.getElementById("btn"); btn.addEventListener("click",function(){ console.info("event-one"); },false); btn.addEventListener("click",function(){ console.info("event-two"); },false); btn.addEventListener("click",function(){ console.info("event-three"); },false); </script>
查看控制台我们会发现,3个事件都会被执行,控制台中依次打印出:“event-one”、“event-two”和“event-three”。
接下来,我们可以来看一下事件捕获的情况。只是介绍了事件捕获,并没有举一个具体的例子。下面我们在DOM2级事件处理程序中来查看事件捕获的过程。代码如下:
<html lang="zh" id="html" class="demo"> <head> <meta charset="UTF-8"> <title>事件捕获</title> </head> <body id="body" class="demo"> <div id="parent" class="demo"> <button id="child" class="demo">点击一下</button> </div> <script type="text/javascript"> window.onload = function(){ var elements = document.querySelectorAll(".demo"); for(var i = 0 ; i < elements.length; i++){ elements[i].addEventListener("click",function(event){ var element = elements[i]; //获取事件 event = event?event:window.event; //获取事件发生的目标 target = event.target?event.target:event.srcElement; console.info("事件源:"+target.id+" , "+target.tagName+", 事件对象:"+this.id); },true); } } </script> </body> </html>
由于在上面的事件处理程序中,第3个参数被设置为 true ,表示在捕获阶段调用事件处理程序。在Firefox浏览器的控制台中得到下面的结果:
从控制台的结果中可以看到,事件源是按钮,事件对象从上往下分别为:
<document> → <body> → <parent> → <child> 。
通过 addEventListener() 方法添加的事件处理程序只能通过 removeEventListener() 方法来移除。移除时传入的参数和添加事件处理程序时的参数一样。注意:通过 addEventListener() 方法添加的匿名函数将无法移除。下面是一个移除DOM2级事件处理程序的例子:
var btn = document.getElementById("btn"); btn.addEventListener("click",function(){ console.info(this.id); },false); ...... btn.removeEventListener("click",function(){/*函数在此处没有用*查看更多关于JavaScript事件-DOM0级事件和DOM2级事件处理的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did31508