作者:李丽媛
联系方式:lly219#gmail.com
日 期:2010-2-26

前言

本文主要正对key event,change event,代理的focus event,移动设备上event测试的初次结果进行讲解,
但在开始之前,我觉得大家还是有必要再温故一下js中 的事件。

一般事件  事件  浏 览器支持  描 述 
onClick IE3|N2|O3 鼠标点击事件,多用在某个对象控制的范围内的鼠标点击  
onDblClick IE4|N4|O 
鼠标双击事件  
onMouseDown IE4|N4|O 
鼠标上的按钮被按下了  
onMouseUp IE4|N4|O 
鼠标按下后,松开时激发的事件  
onMouseOver IE3|N2|O3 
当鼠标移动到某对象范围的上方时触发的事件  
onMouseMove IE4|N4|O 
鼠标移动时触发的事件  
onMouseOut IE4|N3|O3 
当鼠标离开某对象范围时触发的事件  
onKeyPress IE4|N4|O 
当键盘上某个键被按下并且释放时触发的事件 .[ 注意 : 页面内 必须有被聚焦的对象
onKeyDown IE4|N4|O 
当 键盘上某个按键被按下时触发的事件 [ 注意 : 页面 内必须有被聚焦的对象
onKeyUp IE4|N4|O 
当键 盘上某个按键被按放开时触发的事件 [ 注意 : 页面 内必须有被聚焦的对象

页面相关事件 事件  浏 览器支持  描述 
onAbort IE4|N3|O 图片在下载时被用户中断 
onBeforeUnload IE4|N|O 当前页面的内容将要被改变时触发的事件 
onError IE4|N3|O 捕抓当前页面因为某种原因而出现的错误,如脚本错误与外部数据引用的错误 
onLoad IE3|N2|O3 页面内空完成传送到浏览器时触发的事件,包括外部文件引入完成 
onMove IE|N4|O 浏览器的窗口被移动时触发的事件 
onResize IE4|N4|O 当浏览器的窗口大小被改变时触发的事件 
onScroll IE4|N|O 浏览器的滚动条位置发生变化时触发的事件 
onStop IE5|N|O 浏览器的停止按钮被按下时触发的事件或者正在下载的文件被中断 
onUnload IE3|N2|O3 当前页面将被改变时触发的事件 

表单相关事件 事件  浏览器支 持 描述 
onBlur IE3|N2|O3 当前元素失去焦点时触发的事件  [鼠标与键盘的触发均 可] 
onChange IE3|N2|O3 当前元素失去焦 点并且元素的内容发生改变而触发的事件  [鼠标与键盘的触发均可] 
onFocus IE3|N2|O3 当某个元素获得焦点时触发的事件 
onReset IE4|N3|O3 当表单中 RESET的属性被激发时触发的事件 
onSubmit IE3|N2|O3 一个表单被递交时触发的事件 

滚动字幕事件  事件  浏览器支持 描述 
onBounce IE4|N|O  Marquee 内的内容移动至Marquee显 示范 围之外时触发的事件 
onFinish IE4|N|O 当Marquee元素完成需要显示的内容后触发的事件 
onStart IE4|N|O 当Marquee元素开始显示内容时触发的事件 

编辑事件 事件 浏览器支持 描述 
onBeforeCopy IE5|N|O 当页面当前的被选择内容将要复制到浏览者系统的剪贴板前触发的事件 
onBeforeCut IE5|N|O 当页面中的一部分或者全部的内容将被移离当前页面 [剪 贴]并移动到浏览者的系统剪贴板时 触发的事件 
onBeforeEditFocus IE5|N|O 当前元素将要进入编辑状态 
onBeforePaste IE5|N|O 内容将要从浏览者的系统剪 贴板传送 [粘贴]到页面中时触发的事件 
onBeforeUpdate IE5|N|O 当浏览者粘贴系统剪贴板中的内容时通知目标对象 
onContextMenu IE5|N|O 当浏览者按下鼠标右键出现菜单时或者通过键盘的按键触发页面菜单时触发的事件  [ 试试在页面中的 <body> 中加入onContentMenu="return false"就可禁止使用鼠标右键了] 
onCopy IE5|N|O 当页面当前的被选择内容被复制后触发的事件 
onCut IE5|N|O 当页面当前的被选择内容被剪切时触发的事件 
onDrag IE5|N|O 当某个对象被拖动时触发的事件 [活动事件] 
onDragDrop IE|N4|O 一个外部对象被鼠标拖进当前窗口或者帧 
onDragEnd IE5|N|O 当鼠标拖动结束时触发的事件,即鼠标的按钮被释放了 
onDragEnter IE5|N|O 当对象被鼠标拖动的对象进入其容器范围内时触发的事件 
onDragLeave IE5|N|O 当对象被鼠标拖动的对象离开其容器范围内时触发的事件 
onDragOver IE5|N|O 当某被拖动的对象在另一对象容器范围内拖动时触发的事件 
onDragStart IE4|N|O 当某对象将被拖动时触发的事件 
onDrop IE5|N|O 在一个拖动过程中,释放鼠标键时触发的事件 
onLoseCapture IE5|N|O 当元素失去鼠标移动所形成的选择焦点时触发的事件 
onPaste IE5|N|O 当内容被粘贴时触发的事件 
onSelect IE4|N|O 当文本内容被选择时的事件 
onSelectStart IE4|N|O 当文本内容选择将开始发生时触发的事件 

数 据绑定 事 件 浏览器支持 描述 
onAfterUpdate IE4|N|O 当数据完成由数据源到对象的传送时触发的事件 
onCellChange IE5|N|O 当数据来源发生变化时 
onDataAvailable IE4|N|O 当数据接收完成时触发事件 
onDatasetChanged IE4|N|O 数据在数据源发生变化时触发的事件 
onDatasetComplete IE4|N|O 当来子数据源的全部有效数据读取完毕时触发的事件 
onErrorUpdate IE4|N|O 当使用onBeforeUpdate事件触发取消了数据传送时,代替 onAfterUpdate事件 
onRowEnter IE5|N|O 当前数据源的数据发生变化并且有新的有效数据时触发的事件 
onRowExit IE5|N|O 当前数据源的数据将要发生变化时触发的事件 
onRowsDelete IE5|N|O 当前数据记录将被删除时触发的事件 
onRowsInserted IE5|N|O 当前数据源将要插入新数据记录时触发的事件
onAfterPrint IE5|N|O 当文档被打印后触发的事件 
onBeforePrint IE5|N|O 当文档即将打印时触发的事件 
onFilterChange IE4|N|O 当某个对象的滤镜效果发生变化时触发的事件 
onHelp IE4|N|O 当浏览者按下F1或者浏览器的帮助选择时触发的事件 
onPropertyChange IE5|N|O 当对象的属性之一发生变化时触发的事件 
onReadyStateChange IE4|N|O 
当对象的初始化属性值发生变化时触发的事件


更多请参见http://quirksmode.org/dom/events/

正文

1.key event
key event包含了keydown ,keypress 和keyup

当你按下键时,产生了两种属性:
keyCode and charCode

在每一种属性中又分为两个bits的数据:
- the key code
- the character code

从而我们可以看出在keyCode属性中:
- onkeydown: key code
- onkeypress: character code
浏览器支持 :IE,FireFox,Safari,Opera

在 charCode属性中:
- onkeydown: 0
- onkeypress: character code
浏览器 支持 :FireFox,Safari

当你需要获取keyCode属性时,可以这样:
el.onkeydown = function (e) {
    e = e || window.event;    //good custom
    var realKey = e.keyCode;
}
浏览器支持 :IE,FireFox,Safari,Opera

当 你需要获取charCode属性时,可以这样:
el.onkeypress = function (e) {
    e = e || window.event;
    var char = e.keyCode || e.charCode;    //浏览器兼容
}
浏览器支持 :IE,FireFox,Safari,Opera

如何阻止默认的 action?
el.onkeydown = function (e) {
    e = e || window.event;
    var key = e.keyCode;
    if (key is incorrect) {
        // cancel default action
    }
}
浏览器支持 :IE,FireFox,Safari

2.change event
当一个可接受输入的控件发生变化时将会触发change event事件。这是一个非常有用的事件,因为它只在用户改变它的时候发生,而不是当焦点在它上面的时候就触发事件。

- text fields
当把焦点移到上面,但不做任何输入上的改变时,焦点离开将不会触发事件。
只有当焦点移到上面,输入改变,焦点离开后才会触发 事件。
浏览器支持 :IE,FireFox,Safari,Opera

- select boxes
使用鼠标:
当鼠标选中,点击了另外一个选项时,触发事件。
浏览 器支持 :IE,FireFox,Safari,Opera

使用键盘:
当焦点在此控件上时,使用上下键选择 另外一个选项时,触发事件。
浏览器支持 :IE,Opera
喜剧的是这本不应该产生事件,这是一个bug,然而IE和Opera却支持了它。

当 焦点在此控件上时,使用上下键选择另外一个选项且焦点离开时,触发事件。
浏览器支持 :FireFox,Safari

- checkboxes and radios
点击 ,使是否选中的属性发生变化时,触发事件。
浏览器支持 :FireFox,Safari,Opera

点 击 ,使是否选中的属性发生变化且焦点离开时,触发事件。
浏览器支持 :IE
喜剧的是这本不应该产生事件,这是一个bug,然而IE却支持了它。

3. 事件代理
<ul>
    <li><a href=”#”>Multimedialize</a>
        <ul>
            <li><a href=”#”>Sound</a></li>
            <li><a href=”#”>Java applets</a></li>
        </ul>
    </li>
    <li><a href=”#”>Ajaxify</a>
        <ul>
            <li><a href=”#”>Web 2.0</a></li>
            <li><a href=”#”>Web 3.0</a></li>
            <li><a href=”#”>Web 4.0b</a></li>
        </ul>
    </li>
</ul>

当a和li,ul有着相同种类的事件 (如:mouseover, mouseout, click, keydown, keypress)时,当触发a上的事件的时候,li和ul上的事件也会产生。
至于事件产生的顺序将和浏览器的实现相关。FireFox中的顺序 为从内到外,a-li-ul(以下称之为冒泡 )。
当此情况产生时,事件都要进行冒泡,那为什么不绑定到最外面一层呢?那样将节省了 很多事件的绑定。
var dropdown = {
    init: function (dropdown) {
        dropdown.onmouseover = mouseOver;
        dropdown.onmouseout = mouseOut;
    }
}
浏览器支持 :所有
用此方法绑定到最外面一层,其余的ul,li和a就不需要再进行绑定^^ ,这是因为在执行没用绑定方法的元素的事件时,它产生了冒泡 ,可以触发最外一层的同种类的事件(不知道讲清楚没有,不懂得自己动作做下就应 该知道了,讲的我累啊^^)。

但是有一些东西根本不支持鼠标,如果使用键盘,菜单要怎么折叠呢?
我们需要事件来告 诉我们用户是否把焦点移到或离开了链接。
也许你认为可以像下面这样写,但它根本不工作,因为focus和blur不属于冒泡 ,它不 能触发最外一层的同种类的事件 。
var dropdown = {
    init: function (dropdown) {
        dropdown.onmouseover =
            dropdown.onfocus = this.mouseOver;
        dropdown.onmouseout =
            dropdown.onblur = this.mouseOut;
    }
}

在这要介绍一点知 识,我们才能继续前进:
1)鼠标和按键事件
当用户启动一个设备的具体行动时将被触发。
mouseover, mouseout, click, keydown, keypress
一般情况下都冒泡

2)界面事件
当某一事件发生时,不 管它是怎样初始化的,都将被触发
load, change, submit, focus, blur
一般情况下,它们并不冒泡

由 于focus, blur不冒泡, 这样一来的话,它的事件单独绑定在最外一层是就没有了作用,因此需要单独 给每一个都绑定上。
var dropdown = {
    init: function (dropdown) {
        dropdown.onmouseover = this.mouseOver;
        dropdown.onmouseout = this.mouseOut;
        var x = dropdown.getElementsByTagName('a');
        for (var i=0;i<x.length;i++) {
            x[i].onfocus = this.mouseOver;
            x[i].onblur = this.mouseOut;
        }
    }
}


这 样看上去看不雅观,或许我们也可以这样实现。
采用事件捕获来弥补。
事件捕获是一种和冒泡 相反的事件,它被符合W3C标准的 浏览器所支持
浏览器支持:
FireFox,Safari,Opera
冒 泡 :addEventListener('click',fn,false)
事件捕 获:addEventListener('click',fn,true)

问题是,如果你捕获了一个focus事件,在目标元素的父亲将 会被执行事件绑定

冒泡
a上的Focus事件触发时: a.onfocus将被执行

事件捕获:
a上的Focus事件触发时 : ul.onfocus, li.onfocus和a.onfocus将被执行

哎, 为什么会这样呢?我也很奇怪。
也许在这个场景下他们是一样的,目前是没发现什么意义 ,不过也许它是有用的.

var dropdown = {
    init: function (dropdown) {
        dropdown.onmouseover = this.mouseOver;
        dropdown.onmouseout = this.mouseOut;
        dropdown.addEventListener('focus',this.mouseOver,true);
        dropdown.addEventListener('blur',this.mouseOut,true);
    }
}

var dropdown = {
    init: function (dropdown) {
        dropdown.onmouseover = this.mouseOver;
        dropdown.onmouseout = this.mouseOut;
        if (dropdown.addEventListener) {
            dropdown.addEventListener('focus',this.mouseOver,true);
            dropdown.addEventListener('blur',this.mouseOut,true);
        }
    }
}
浏览器支持 :FireFox,Safari,Opera

杯 具的IE怎么办呢?它并不支持addEventListener,但是幸运的是它支持focusin和focusout事件,这两个事件类似于focus 和blur,可喜的是它们并不是冒泡 .

var dropdown = {
    init: function (dropdown) {
        dropdown.onmouseover = this.mouseOver;
        dropdown.onmouseout = this.mouseOut;
        if (dropdown.addEventListener) {
            dropdown.addEventListener('focus',this.mouseOver,true);
            dropdown.addEventListener('blur',this.mouseOut,true);
        }
        dropdown.onfocusin = this.mouseOver;
        dropdown.onfocusout = this.mouseOut;
    }
}
浏览器支持 :IE,FireFox,Safari,Opera

4. 移动设备上事件的初次测试

移动的web时代来临了
在移动电话上有 3中输入模式:
- 触摸
- 光标(或者说,假光标)
- 上下左右按键导航

Opera Mini 4.2 on Nokia E71
假光标输入模式

Opera Mobile 8.00 on Motorola V3xx
上下左右导航

NetFront on Sony Ericsson K770i
上下左右导航 ,但是如何选择一个连接,去点击它 呢?

移动电话的事件

在这样一个环境中,“mouseover” 意味着什么,那mouseout, mousemove, mousedown, mouseup又意味着什么呢?
还有点击呢?

在一个<div>元素中 添加了一个“click”事件,让我们来看看会有什么情况发生。
首先呢,有一些好消息:
S60 WebKit on Nokia E71
输入模式:假光标
和桌面浏览器效果一样。

Opera Mobile 9.5 on HTC Touch Diamond
输入模式:触摸
和iPhone的效果一样。

因此 Nokia 的光标输入模式的行为和台式电脑一样,然而最新的Opera行为和iPhone的一样。
iPhone/Opera模式:
当用 户触摸某个元素——mouseover, mousemove, mousedown, mouseup以及点击的触发和:hover style将被应用。
当用户触摸另外一个元素时,mouseout事件的触发和 :hover 样式将被移走。

现在呢,让 我们来看一下坏消息吧:
Blackberry Storm
输入模式:假光标
没 有mouseover,mouse out, mouse move

NetFront on Samsung F700
输入模式:触摸
点击在哪里呢?

在这里只 列出了19种浏览器中的4种,然而现在移动电话上有一大堆的浏览器。
不过对移动手机来说,可以给出一般的事件规则
-使用 点击事件(让我们礼貌而坚定的拒绝那些按键浏览器)
-忘记鼠标事件吧
-使用resize和orientationchange事件
orientationchange 只被iPhone和Blackberry所支持
resize只被Opera和所有的WebKits所支持
NetFront没有被任何所支 持——太糟糕了。
-使用按键事件去设置一般允许的按键;而不是显示出用户输入的表单字段.你应该显示出字段的值。


参 考
JavaScript Event By PPk
W3C