我们已经介绍了对象的概念,我们可以通过定义属性和方法来定义对象。不仅如此,对象还具有与之相关的事件。由于javascript中的内建对象并没有相关的事件,因此在前面的内容中我们并没有提到事件这个概念。但是,bom对象则具有相关的事件。
那么,bom对象都具有哪些事件呢?
当特定的操作发生或者状态改变时,事件将被触发。例如,当用户在页面上单击时、或单击页面上的超链接时,或者当鼠标指针移过某段文字时,都可能触发相应的事件。另外一个经常用到的事件是页面的load事件,当页面加载时将触发这个事件。
那么,事件对我们有什么用呢?
为了说明事件的作用,让我们来看一个例子,当用户在页面上的任何地方单击鼠标时,我们希望弹出一个菜单。假定我们写好了产生弹出菜单的函数,但是我们怎么知道什么时候让菜单弹出呢?或者换句话说,我们什么时候调用这个产生弹出菜单的函数呢?因此,我们需要以某种方法捕获用户单击页面的事件,并且确保一旦单击页面的事件发生时,产生弹出菜单的函数即被调用。
为了实现这个功能,需要使用一种称为事件处理器(event handler)的机制。当事件发生时,事件处理器将连接到需要执行的事件处理代码。事件处理器提供了当事件发生时捕获事件、并且执行相应的事件处理程序的机制。通常我们把在代码中加入事件处理器称为“将事件处理代码连接到事件”。这有点类似于设置一个闹钟—— 当某个事件发生时,使闹钟振铃。对于一个闹钟来说,这个触发事件就是当到达某一确定的时间点时。
事件处理器由关键字on加上要处理的事件名组成。例如,click事件的事件处理器为onclick,load事件的事件处理器为onload。
通过事件处理器,可以使用多种方法将事件处理代码连接到事件。在本章中,我们将介绍两种最简单的办法。这两种方法不但被当前的浏览器所支持,而且自netscape 2浏览器就开始使用,甚至更早的浏览器也支持这两种方法。在第12章中将介绍其他较新的且更加易于标准化的添加事件的方法。
第一种方法是最常见的,即把事件处理器和关联的代码作为html标记的属性和属性值添加在相应的html标记中。
下面将创建一个简单的html页面,该页面用<a>标记创建了一个超链接。相应地,浏览器将创建一个对应的a对象。我们都知道,a对象具有一个click事件,当用户单击超链接时,将触发该超链接的click事件。这个页面的代码如下:
<html>
<body>
<a href="somepage.htm" name="linksomepage">
click me
</a>
</body>
</hml>
按照现在的情况,这个页面除具有一个超链接之外并无其他的功能。单击超链接,将导航到一个新的页面somepage.htm,这是我们创建的另一个页面。对于超链接,我们还没有加上事件处理器。
正如上文所述,要为某个bom对象添加事件处理器,最常用且最简单的方法就是直接将事件处理代码作为html标记的属性,添加在html标记中。在本例中,需要捕获的就是由<a>标记所定义的a对象的click事件。当用户单击这个超链接时,我们希望能捕获该click事件,并执行相应的事件处理代码。因此,需要为<a>标记添加一个事件处理器,即onclick事件处理器。可以把onclick事件处理器作为一个属性添加在<a>标记中,并把该属性的值设置为事件触发时要执行的处理代码。
可以将<a>标记修改为如下代码:
<a href="somepage.htm" name="linksomepage" onclick="alert('you clicked?')">
click me
</a>
现在,为<a>标记添加了一个属性:onclick="alert('you clicked?')"。此时,当用户单击了这个超链接,将弹出一个消息对话框。之后,超链接才会执行默认的功能,并链接到由<a>标记的href属性所定义的页面。
如果连接到事件处理器的代码只有一行,这个办法就是可行的。但是当超链接被单击时,所执行的事件处理代码是多行时,那该怎么办呢?
其实很简单,我们只需要把希望执行的事件处理代码定义为一个函数,然后在onclick事件处理器中调用这个函数。请看下面的代码:
<html>
<body>
<script language="javascript">
function linksomepage_onclick()
{
alert('you clicked?');
return true;
}
</script>
<a href="somepage.htm" name="linksomepage" onclick="return
linksomepage_onclick()">
click me
</a>
</body>
</html>
在上面的脚本块中,创建了一个linksomepage_onclick()函数,这是一个标准的函数。同时为了提高代码的可读性,我们为函数取了一个具有描述性的名字。此处,使用了objectname_event()这样的形式作为函数的名称。采用这种形式的名称,可以很直接地看到这个函数与页面上的哪一个对象关联,并且连接的是哪一个事件。因此,在上面这个例子中,将函数定义为linksomepage_onclick(),即这个函数关联的是名为linksomepage的超链接对象的onclick事件处理器。这种命名规范只是程序员的一种约定俗成,它并不是强制性的。只要在代码中使用一致的命名规范,我们也可以使用自己喜欢的其他命名方式。
现在onclick属性连接到了调用linksomepage_onclick()函数的代码。因此,当用户单击了这个超链接,linksomepage_onclick()函数就将被执行。
值得注意的是,linksomepage_onclick()函数具有一个返回值,且在本例中,返回值为true。此外,在定义onclick属性时,在函数名之前使用了一个return语句,将函数的返回值返回给onclick属性,这是为什么呢?
由事件处理器 onclick="return linksomepage_onclick()"返回的值将被javascript用来决定超链接是否执行它的默认行为,即是否链接到一个新页面去。如果返回值为true,则超链接将执行它的默认行为,并链接到somepage.htm页面。如果返回值为false,则默认的事件处理功能—— 链接到somepage.htm页面—— 将不会被执行,即超链接的默认事件处理行为被取消了。我们可以修改一下代码以进行测试,如下所示:
function linksomepage_onclick()
{
alert('this link is going nowhere');
return false;
}
此时,你将发现仅仅弹出了一个消息对话框,超链接并没有提供链接到somepage.htm页面的功能。
某些对象和事件并不会使用事件处理器的返回值,因此有的时候返回值是多余的。另外,返回值为false时也并不一定总是能够取消对象的默认行为。出于浏览器发展的历史原因,对于某些浏览器有时当返回值为true时将取消对象的默认行为。通常,最好将返回值设置为true,在遇到特殊情况时再作出相应的处理,这样做比较保险。
某些事件并不是直接由用户的行为所触发。例如,window对象具有load事件和unload事件,当页面加载完毕时将触发load事件,而当页面卸载时,将触发unload事件(页面卸载指的是用户关闭了浏览器,或者打开了其他页面)。
实际上,window对象的事件处理器应放在<body>标记中。例如,要为window对象的load事件和unload事件添加相应的事件处理器,可以使用如下代码:
<body language="javascript" onload="myonloadfunction()"
onunload="myonunloadfunction()">
注意,这里把<body>标记的language属性设置为javascript,因为<body>标记并不包含在定义javascript脚本块的<script>标记内。通常情况下,javascript就是默认的脚本语言,因此该language属性也可以省略。
新闻热点
疑难解答