程序员人生 网站导航

JavaScript Event学习第一章:Event介绍

栏目:jscript时间:2014-05-29 02:25:12

Events是每一个JavaScript程序核心。什么是事件处理,它有什么问题和怎样写出跨浏览器的代码,我将在这一章做一个概述。我也会提供一些有精彩的关于事件处理程序的细节的文章。

没有event就没有脚本。可以看看任何有JavaScript代码的网页:几乎所有的例子都有一个事件触发了脚本。原因非常简单。JavaScript就是给你的页面添加内部活动:用户做一些事情然后页面做出回应。

因此JavaScript就需要一个方法能够检测到用户的动作然后才能知道什么时候做出反应。这还需要知道那个函数会被执行,函数会做一些你认为的给你的网页增色的动作。这些文字描述了如何去写这样的脚本。虽然不容易,但是这是一个很让人满足的工作。
当用户做了什么事情event就发生了,当然还有一些event不会直接被用户触发:比如load事件会在页面装载完毕的时候触发。

JavaScript能够检测一些event。从Netscape 2开始,在HTML元素上添加event hanlder就成为可能。这些事件处理函数等待一个确定的事件,比如点击一个链接。当他发生的时候,事件就会通过你指定的JavaScript代码来执行。

当用户做出动作他就引发了一个事件。当你的代码让页面对这个动作做出回应,交互就产生了。

事件处理程序的历史
如上所述,没有事件处理程序就没有在页面添加JavaScript的必要。那些能对用户动作做出反应的就是最好的脚本。因此,当Netscape发布他的第二版支持JavaScript的浏览器的时候,他同时也支持event。

Netscape模式
Netscape只支持一小部分事件。Mouseover和mouseout的快速流行时因为当鼠标滑入时改变图片而滑出时又返回到原来的状态这个很炫的效果。而且可以看到用户是否提交了表单或者重置了表单,这样在客户端的验证也就成为了可能。浏览器还能监测表单的某一项获得或者失去了焦点或者页面完成下载又或者开始关闭。在如今看来这些都是非常稀松平常的事情,但在那个时候那可是革命性的。因为你能对用户的动作做出反馈,所以真正的交互才变成可能。
在最古老的表单的事件处理程序看起来是这样的。当用户点击了链接,事件处理程序就被执行了然后弹出对话框。

<a href="somewhere.html" onclick="alert('I've been clicked!')">

注意到这种最古老的处理事件的方法事实上就是Netscape的标准是很重要的。如果想要JavaScript工作,其他的浏览器包括IE都得遵从Netscape 2和3的处理事件的标准。因此这些最古老的事件和事件处理程序在任何JavaScript浏览器中都能很好的运行。

现在的事件模式
然而,相比之前的介绍,现在的事件处理程序有了很大的变化。第一就是数量上急剧增长。对HTML元素的事件处理程序的注册的方法也有很大的变化。现在完全可由JavaScript设置。不再需要大量的附着于代码之上,你可以写一些很简单的代码来设置所有的事件处理程序。
V4浏览器也提供了关于事件的很多信息。鼠标在哪?什么时候事件发生?键盘按下了么?最终,浏览器必须要对一个元素和这个元素的父元素对同一个动作都有事件处理程序做出选择。哪个事件先触发呢?
因为这个功能而更加加剧了浏览器之间的战火,Netscape和微软制订了几乎互不兼容的两套事件模型。最近第三种模型开始显现,这是由w3c发布的DOM Event specification 。虽然有一个严重的缺陷,w3c模型是基于旧的Netscape模型但是更加的广义和通用,这是一份非常杰出的作品,添加了很多有趣的函数,也解决了一些老的事件模型存在的问题。
既然存在三种模型,所以事件处理程序也就不能以同样的方式在所有的浏览器里面运行。

浏览器的兼容性问题

我们继续。就像DHTML,w3c DOM或者其他高级的脚本技术一样,我们对于代买的每一个字节都要小心。在IE中使用stopPropagation()或者在Netscape中使用srcElement都会导致严重的错误而使我们的代码毫无用处。因此在使用方法或者属性之前我们必须对浏览器的支持性做必要的检查。
一个简单的代码片段如下:

if (Netscape) {
use Netscape model
}
else if (Explorer) {
use Microsoft model
}

这只是解决问题的一个开始而已。最近的浏览器能运行的事件处理程序的数量是巨大的,除非你的代码不允许除了Netscape或者IE其他少数浏览器运行。
所有的小众浏览器都必须不那么光彩的决定支持那种事件模型。Konqueror/Safari通常都选择严格的按照W3C的标准执行。Opera和iCab通常都会支持大部分的老的Netscape模型和一些微软的模型。我对其他的更小众的浏览器还没有做研究。
但是其他的更小众的浏览器可能选择支持微软处理事件的方法,同时又有W3C和老的Netscape的属性。这都没什么问题,总之他们都是以他们自己的方法支持我们知道的模型。你的代码应该没有问题。

不要使用浏览器类型检测
首先,永远永远都不要使用浏览器检测,这是通向地狱的捷径。任何代码如果使用navigator.userAgent来做事件模型的检测,那简直比没用还没用应该直接拉出去弹JJ。
第二,不要被DHTML的object detection的事件对象检测所迷惑。当你写DHTML的时候通常检测DOM的支持性,比如,if(document.all)。如果支持,那么代码如果使用Microsot的all容器就能搞很好的运行。
但是DHTML和事件处理程序有不同的浏览器兼容性模式。比如,Opera 6支持W3C DOM的一部分但是不支持W3C event模型。因此DHTML对象检测在Opera下会做出错误的决定。所以代码使用if(document.layers)或者其他的事件模型检测都是不正确的。

正确的问题
那么我们怎么办?Event属性的名字造成了这些问题。如果我们针对具体的对象探测使用不同的办法,基本上能解决99%的浏览器的不兼容问题。只有鼠标位置非常的麻烦,其他的都比较简单了。
另外,最好根本就不要去想那三个事件模型。实际上,我们应该去理解四种事件注册模型,两种事件执行模型和两种事件顺序。 这里可以快速查看下事件兼容性列表。

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐