<input type="button" value="click me" onclick="try{show();}catch(ex){}">
2.这样扩展事件实例程序的作用域链在不同的浏览器中会导致不同的结果(例4中我是在chrome中查看的作用域链,其他浏览器不一定是这样的,请注意)。不同JavaScript引擎遵循的标识符解析规则略有差异,很有可能会在访问非限定对象成员时出错。
3.HTML和JavaScript代码紧密耦合。 结果是:如果要更换事件处理程序,就必须改动两个地方--HTML代码和JavaScript代码。
那么怎么解决上面的问题呢? DOM0级事件处理程序是一个不错的选择!
第二部分:DOM0级事件处理程序DOM0级事件处理程序用的也非常普遍。之所以成为DOM0级,我认为是当时还没有出DOM标准,而IE和Netscape Navigator两者使用的时间处理程序(不知是否合理,望批评指正)。 总之,我们先看看下面的例子吧。
例6:
<button id="button">点我</button> <script> var button=document.getElementById("button"); button.onclick=function(){ alert("clicked"); } </script>
即我们先在script中取得元素的引用,然后再将一个函数赋值给onclick事件处理程序。 之前介绍过,事件处理程序即为函数,而button.onclick这种形式即函数作为了对象的方法。那么对象的方法即事件处理程序是在元素(对象)的作用域中运行而非在全局作用域中运行的,因为方法是属于对象的。(注意:例4中事件处理程序是在全局作用域中运行的)。 如果这个函数中存在this关键字,那么this就会指向这个对象。下面我们在浏览器中证明事件处理程序是在元素的作用域中运行。
我们看到alert("clicked");确实是在button中运行的。
我们还可以通过下面的方式删除通过DOM0级方法指定的事件处理程序。
button.onclick=null;
通过上面的分析我们可以知道DOM0级事件处理程序是非常不错的,它解决了HTML事件处理程序的三个缺点:时差问题、作用域链导致的不同浏览器表现不一致问题和HTML和JavaScript紧密耦合问题。
但是,DOM0级事件处理程序并不是完美的,它同样有两个缺点:
我们不能给一个元素同时添加两个事件。
我们不能控制元素的事件流(捕获or冒泡)。
对于第二个问题后面会讲到,第一个问题举例如下:
<button id="button">点我</button> <script> var button=document.getElementById("button"); button.onclick=function(){ alert("clicked"); } button.onclick=function(){ alert("again"); }
虽然我对同一个元素设置了两个事件处理程序,但是最终的结果是:只有第二个事件有效(覆盖了第一个事件)。当然,人类是聪明的动物,DOM2级事件很好的解决了这个问题!
第三部分:DOM2级事件处理程序DOM2级事件处理程序定义了两个方法:
addEventListener() ---添加事件侦听器
removeEventListener() ---删除事件侦听器
在博文的开头我就提到了事件处理程序即事件侦听器。这两个方法都接收三个参数:
要处理的事件名(注意:是时间名,所以没有on!),如click、mouseover等。
作为事件处理程序的函数,如function(){alert("clicked");}
表示事件流方式的布尔值。false为冒泡阶段调用事件处理程序;true为捕获阶段调用事件处理程序。
下面通过两个例子加深理解:
例7:
<button id="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。