click,load,mouseover都是事件的名字,而响应某个事件的函数就叫做事件处理程序(或事件侦听器)。事件处理程序的名字以'on'开头,onclick,onload
事件处理程序(html事件处理程序,dom0级事件处理程序,dom2级事件处理程序,ie事件处理程序,跨浏览器事件处理程序)
html事件处理程序
1、内置js
<input type='button' value='click me' onclick='alert("clicked")'/>
当点击这个按钮时,就会显示一个警示框
注意:不能在其中使用未经转义的html语法字符 例如双引号(""),小于号(<),大于号(>)。
<input type='button' value='click me' onclick='alert("clicked")'/>
2、函数调用
<script type='text/javascript'> function showMessage(){ alert('Hello world'); } </script> <input type='button' value='click me' onclick='showMessage()'/>
事件处理程序中的代码在执行时,有权访问全局作用域中的任何代码
3、其他
<input type='button' value='click me' onclick='alert(value)'/> = <input type='button' value='click me' onclick='alert(this.value)'/>
this值等于事件的目标元素
<input type='button' value='click me' onclick='alert(event.type)'/>
通过event变量,可以直接访问事件对象,不用自己定义它
<form action="" post='post'> <input type='text' value='click me' name='username'/> <input type='button' value='click me' onclick='alert(username.value)'/> </form>
扩展作用域,让事件处理程序无需引用表单元素就能访问其他表单字段
html事件处理程序的缺点:
1、如果用户在html元素一出现在页面上就触发相应的事件,但当时的事件处理程序有可能尚不具备执行条件。
2、这样扩展事件处理程序的作用域链在不同浏览器中会导致不同的结果,不同js引擎遵循的标识符解析规则略有差异,很可能会在访问非限定对象成员时出错。
3、html与js代码紧密耦合。如果要更换事件处理程序,就要改动两个地方:html代码和js代码。
DOM0级事件处理程序
通过js指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性。eg:
<script> var btn = document.getElementById('myBtn'); btn.onclick=function(){ alert('clicked'); } </script> <input type='button' value='click me' id='myBtn'/>
使用dom0级方法指定的事件处理程序被认为是元素的方法。因此,这时候的事件处理程序是在元素的作用域中运行;换句话说,程序中通过this引用当前元素
var btn = document.getElementById('myBtn'); btn.onclick=function(){ alert(this.id); }
在事件处理程序中通过this访问元素的任何属性和方法。以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理
btn.onclick = null;//删除事件处理程序
将事件处理程序设置为null后,再单击按钮将不会有任何动作发生
DOM2级事件处理程序
var btn = document.getElementById('myBtn'); btn.addEventListener('click',function(){ alert(this.id); },false)
DOM2级事件定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener();所有dom都包含这两个方法,并且它们都接受3个参数:
要处理的事件名
作为事件处理程序的函数
一个布尔值(true表示捕获阶段调用事件处理程序,false表示冒泡阶段调用事件处理程序)
特点:
1、与dom0级一样,这里添加的事件处理程序依附在作用域中运行(要先加载dom,再加载js)
2、可以添加多个事件处理程序
var btn = document.getElementById('myBtn'); btn.addEventListener('click',function(){ alert(this.id); },false) btn.addEventListener('click',function(){ alert('Hello world'); },false)
3、通过addEventListener()添加的事件处理程序只能使用removeEventListener()移除,移除时传入的参数与添加处理程序时的参数相同,这也意味着addEventListener()添加的匿名函数将无法移除
var btn = document.getElementById('myBtn'); btn.addEventListener('click',function(){ alert(this.id); },false) //省略其它代码 btn.removeEventListener('click',function(){ //没有用 alert(this.id); },false)
看似使用了相同的参数,实际上,第二个参数与传入的那个时完全不同的函数
var btn = document.getElementById('myBtn'); var handler = function(){ alert(this.tid) } btn.addEventListener('click',handler,false) //省略其它代码 btn.removeEventListener('click',handler,false);//有效
IE事件处理程序
IE实现了与DOM中类似的两个方法:attachEvent()和detachEvent()。这两个方法接受相同的两个参数:事件处理程序名称与事件处理程序函数,由于IE8及更早版本支持事件冒泡,所以通过attachEvent()添加的事件处理程序都会被添加到冒泡阶段
var btn = document.getElementById('myBtn'); btn.attachEvent('onclick',function(){ alert('Clicked'); alert(this === window); //true }) btn.attachEvent('onclick',function(){ alert('Hello World'); })
注意:
1、dom0在其所属元素的作用域内运行,使用attachEvent()方法的情况下,事件处理程序会在全局作用中运行,this等于window,如果在编写跨浏览器的代码时,牢记这一区别非常重要
2、与addEventListener类似,可以为一个元素添加多个事件处理程序
3、与dom不同的是,这些事件处理程序不是以添加它们的顺序执行,而是以相反的顺序被触发,单机这个例子,首先会看到hello world,然后才是clicked
4、使用attachEvent()添加的事件可以通过detachEvent()来移除,条件是必须提供相同的参数。与DOM方法一样,这也意味着添加的匿名函数将不能被移除
var btn = document.getElementById('myBtn'); var handler = function(){ alert('Clicked'); } btn.attachEvent('onclick',handler); //这里省略了其他代码 btn.detachEvent('onclick',handler);
跨浏览器的事件处理程序
要保证处理事件的代码能在大多数浏览器下一致运行,只需关注冒泡阶段。第一个要创建的方法是addHandler(),它的职责视情况分别使用dom0级方法、dom2级方法或ie方法来添加事件
var EventUtil = { addHandler:function(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false); }else if(element.attachEvent){ element.attachEvent('on'+type,handler) }else{ element['on'+type] = handler; } }, removeHandler:function(element,type,handler){ if(element.removeEventListener){ element.removeEventListener(type,handler,false); }else if(element.detachEvent){ element.detachEvent('on'+type,handler); }else{ element['on'+type] = null; } } }