【原创翻译】深入理解javascript事件处理函数绑定三部曲(一)——早期的事件处理函数
原文并非是是三部曲,而是一系列讲解javascript基础的文章。我是把其中三篇抽出来,作为一个整体,对理解事件绑定模型相当有帮助,原文在这里http://www.quirksmode.org/js/events_early.html
今天我会解释最早期的添加事件处理函数的方法,这种方式甚至在第二代浏览器(Version2 Browers)中也得到支持
早期的浏览器只支持一种函数绑定方式,由Netscape发明的。并且至今还不存在任何的兼容性问题,由于当时Netscape的龙头地位,微软如果也想创造一款能运行javascript的浏览器,它就必须服从Netscape的指定标准。所以这种模式在所有javascript浏览器中都行得通——除了Mac上的IE3,它压根对javascript中的”事件”不支持
绑定事件处理函数
在行内事件绑定模型(inline event registration model)中,处理函数作为它们服务的html元素的一个属性被添加,就像
<A HREF="somewhere.html" onClick="alert('I\'ve been clicked!')">
当在这个超链接上有点击事件发生时,处理函数被调用并且执行这段脚本:一个弹出框出现了。你也可以调用一个javascript函数:
<A HREF="somewhere.html" onClick="doSomething()">
对于事件名称中的大小写的混合(如onClick,onMouseOver)只是习惯问题,HTML对大小写并没有严格规定,所以你想大小写都行。但是在XHTML中所有属性名称都必须小写,所以如果你使用的是XHMTL你必须写如成onclick和onmouseover
别使用它
尽管行内事件绑定模型有相当长一段时间并且非常可靠,它也有一个严重的缺陷,它要求javascript脚本被写入XHTML的结构层(于html标签混在一起),但是它并不应该在那。
所以我强烈建议你并不应该使用这种模型,请看我这篇文章《谈脚本与结构层的分离》,里面进行了全面的讨论
默认行为(Default Action)
在那之后不久Netscape开始打html元素默认行为(如超链接默认行为是跳转页面)的主意,如考虑如何阻止默认行为发生。要补充的是,它的这个模型还是在浏览器大战中生存了下来,并且被标准化,所以至今它仍然能工作良好。
和我们所知道的一样,当用户点击一个超链接,浏览器根据它的href属性跳转到指定的页面。这就是所谓的超链接点击事件的默认行为。但是如果你同时也给这个链接的点击事件绑定了一个onclick处理函数该怎么办?它会被执行吗,在什么时候?
<A HREF="somewhere.html" onClick="doSomething()">
在这个超链接中存在单击处理函数的例子中,处理函数必须想方设法首先被执行。因为一旦默认行为发生,新页面被加载,在浏览器内存中的旧页面和它的那些处理函数会被统统抹去。所以如果想让单击处理函数被执行,它必须先于默认行为。
这被视为函数绑定的重要原则,如果事件同时引起默认行为发生和处理函数的执行:
- 处理函数首先被执行
- 默认行为才能随后发生
所以在我们之前的例子中doSomething()会被首先执行,在那之后浏览器才会根据链接跳转页面。
阻止默认行为
当上面那些原则被确定之后,人们又开始考虑是否要阻止默认行为发生。在之前例子中,阻止浏览器根据链接跳转页面是可能的
因此规定根据事件处理函数的返回布尔值(true or false)判断是否阻止。当返回false时,就意味着“不发生默认行为”,如果我们把我们的例子改为:
<A HREF="somewhere.html" onClick="doSomething(); return false">
则超链接永远也不会起作用。函数被执行并且返回一个false,告诉浏览器别执行默认行为
当然也可以让函数来决定是否执行默认行为,把例子改为:
<A HREF="somewhere.html" onClick="return doSomething()">
function doSomething()
{
return confirm('Do you really want to follow this link?')
}
这是非常简单用户交互,用户被问到这个问题。如果他的答案是”OK”,函数返回true。如果他选择”Cancel”,则返回false。这个结果被捕获,被返回给事件自己,如果结果是false,则默认行为被取消,超链接不起作用
但无论如果,你无法阻止所有的默认行为发生,如unload就不可以被阻止。设想用户正在关闭浏览器窗口——触发了这个窗口中页面的unload事件,如果你可以阻止这种unload,那就意味着无视用户的意愿而让窗口仍然打开?门都没有
你当然可以尝试阻止unload,通过使用微软的beforeunload事件属性。但是想象一下,当用户被想关闭窗口时,还要被询问是否确定,会让他感到一点奇怪吧。所以最好别用它。
用返回false来阻止默认行为的发生,在所有浏览器中都是有效的,它是事件处理函数最基本的一部分。现代的事件处理模型以及添加了阻止默认行为的新方法:
- W3C给事件添加了preventDefault()方法,如果你调用它默认行为被阻止
- 微软给事件添加了returnValue属性,如果设为false,默认行为被阻止
但是你不需要用上他们,一个简单的return fasle就足够了
window.status
return false中有一个例外,当用户把鼠标移上一个超链接时,你同时想改变状态栏的文字,这也是一种阻止默认行为——阻止状态栏显示href的链接地址。在这种情况下必须返回true
<A HREF="somewhere.html"
onMouseOver="window.status = 'This link goes somewhere'; return true">
如果你不这么做,代码便不会工作。没有人知道这是为什么,就当它是许许多多奇怪的事情之一。
this关键字
在javascript中this关键字代表拥有它的函数。在事件处理函数中,this是对正在处理事件html元素的引用,这一点非常有用,它可以根据这一点访问它。
不幸的是,虽然this关键字非常有用,但是如果你不是非常清楚它如何工作的话,它也非常难使用。我在另一篇文章有谈论。在这我把它在行内模型中的使用作一个简短的小结:
<A HREF="somewhere.html" onClick="doSomething(this)">
function doSomething(obj)
{
// obj now refers to the link
}
你把一个对超链接的引用,也就是存储在obj中,传递给函数。现在你不需要为了找用户正在点击元素,而搜索整个页面:它被安全的存贮在obj中,现在可以这么做:
<A HREF="somewhere.html" onClick="return doSomething(this)">
<A HREF="somewhereElse.html" onClick="return doSomething(this)">
function doSomething(obj)
{
var linkTo = obj.href;
return confirm('Do you really want to follow the link to ' + linkTo + '?')
}
这个函数接收到一个变量obj,它是对超链接的引用。你可以访问它的href属性,并且把它用在confirm对话框中。这么做技巧在于你可以把这个处理函数添加到页面中的任何超链接中,:它总是能正确的提示现在正在被点击的超链接
继续