即我们先在script中取得元素的引用,然后再将一个函数赋值给onclick事件处理程序。 之前介绍过,事件处理程序即为函数,而button.onclick这种形式即函数作为了对象的方法。那么对象的方法即事件处理程序是在元素(对象)的作用域中运行而非在全局作用域中运行的,因为方法是属于对象的。(注意:例4中事件处理程序是在全局作用域中运行的)。 如果这个函数中存在this关键字,那么this就会指向这个对象。下面我们在浏览器中证明事件处理程序是在元素的作用域中运行。
我们看到alert("clicked");确实是在button中运行的。
我们还可以通过下面的方式删除通过DOM0级方法指定的事件处理程序。
button.onclick=null;
通过上面的分析我们可以知道DOM0级事件处理程序是非常不错的,它解决了HTML事件处理程序的三个缺点:时差问题、作用域链导致的不同浏览器表现不一致问题和HTML和JavaScript紧密耦合问题。
但是,DOM0级事件处理程序并不是完美的,它同样有两个缺点:
1.我们不能给一个元素同时添加两个事件。
2.我们不能控制元素的事件流(捕获or冒泡)。
对于第二个问题后面会讲到,第一个问题举例如下:
<button>点我</button> <script> var button=document.getElementById("button"); button.onclick=function(){ alert("clicked"); } button.onclick=function(){ alert("again"); }
虽然我对同一个元素设置了两个事件处理程序,但是最终的结果是:只有第二个事件有效(覆盖了第一个事件)。当然,人类是聪明的动物,DOM2级事件很好的解决了这个问题!
第三部分:DOM2级事件处理程序
DOM2级事件处理程序定义了两个方法:
addEventListener() ---添加事件侦听器
removeEventListener() ---删除事件侦听器
在博文的开头我就提到了事件处理程序即事件侦听器。这两个方法都接收三个参数:
1.要处理的事件名(注意:是时间名,所以没有on!),如click、mouseover等。
2.作为事件处理程序的函数,如function(){alert("clicked");}
3. 表示事件流方式的布尔值。false为冒泡阶段调用事件处理程序;true为捕获阶段调用事件处理程序。
下面通过两个例子加深理解:
例7:
<button>点我</button> <script> var button=document.getElementById("button"); button.addEventListener("click",function(){ alert(this.id); },false); button.addEventListener("click",function(){ alert("another event"); },false); </script>
结果:第一次弹出窗口:button。
第二次弹出窗口:another event。
结论:通过DOM2级事件处理程序,我们可以为同一个元素添加两个或更多的事件。事件根据顺序依次触发。且this同样指向当前元素,故函数在元素的作用域中执行。
this分析:和前面的DOM0级事件处理程序一样,这里的addEventListener同样也可以看作对象的方法,不同之初在于,DOM0级的方法需要另外一个函数来赋值,而这里的方法是DOM2级规范预定义的。
removeEventListener()这个删除事件处理程序的方法值得注意的是:使用addEventListener()来添加的事件处理程序只能通过它来移除,且需要传入相同的参数。
例8:
<button>点我</button> <script> var button=document.getElementById("button"); button.addEventListener("click",function(){ alert(this.id); },false); button.removeEventListener("click",function(){ alert("another event"); },false);
上述代码貌似可以移除click的事件处理程序,但是通过实验证明是不可以的,原因是:事件处理程序为匿名函数时无法移除。看下面的成功移除的例子:
例9:
<button>点我</button> <script> var button=document.getElementById("button"); function handler(){ alert(this.id); } button.addEventListener("click",handler,false); button.removeEventListener("click",handler,false); </script>
成功移除!
注意:1.传入方法的handler没有(),是因为这里都只是定义函数,而不是调用,需要注意。
2.这两个方法的第三个参数都是false,即事件处理程序添加到冒泡阶段。一般不使用true,因为低版本的IE不支持捕获阶段。