处理IE中Bubble Up 事件模型的细节
我们都知道,IE实现的是一种叫做bubble up的事件模型。在这个模型中我们的事件可以通过Web页元素的hierarchy,从事件触发元素向其parentElement传递,除非被显示的cancel。不过在一些复杂的事件响应处理中,还有很多细节需要仔细考虑。
对于Web元素可侦听的事件来说,大多数的事件都是比较简单的。比如什么onload、onclick、onkeypress、onmousedown、onmouseup等等。但是却有一些是比较麻烦的,比如onmousemove、onmouseover和onmouseout。为什么说这几个比较麻烦呢?因为这几个事件一般会比较频繁的被触发,而且onmouseover和onmouseout还更加特殊,这两个事件还会影响event的toElement和fromElement属性。
同时onmouseover和onmouseout以及onmousemove还是不确定的事件,什么意思呢?就是说当鼠标从html元素上移动时,不是100%能触发这几个事件。这是因为,浏览器中dhtml的事件触发是在浏览器事件处理进程合理idle的时候,根据用户的和浏览器的交互遍历dhtml树的状态来产生的。当浏览器事件处理进程太忙,或者用户交互过于密集的时候,由于IE没有事件队列,没有被处理的事件就再也不会出发了。这里的事件丢失是完全可以接受的,如果不作丢弃浏览器的交互反而会非常的难用。就常常会出现这种情况,有时当我们的windows太繁忙而不立即响应鼠标事件时,我们却到处点击鼠标想"激活"系统,系统在忙完那个费时的处理后,会来接着处理message queue里的一大堆message,我们就能看到刚才点过的鼠标操作都被windows连续处理了。
回头继续说我们事件处理中的细节问题。看下面这个示例:
this is a inner span element.
我们在最外面的蓝色span元素中监听事件onmouseover,代码为:
当我们把鼠标移入蓝色region,我们看到status上显示"blue"。我们继续在蓝色region中移动鼠标时(不要和别的边相交),我们发现onmouseover在blue时的timestamp不变,说明如果鼠标已进入一个element的区域中,就不再触发onmouseover了(否则就成了onmousemove了)。可是这个时候如果我把鼠标移入绿色或红色的region中,我们发现又有新的onmouseover事件被触发并被蓝色span元素截获。而且不断的在绿色、红色及蓝色regions中移动鼠标,timestamp也在不断地变,说明总有onmouseover事件被触发。
其实既然都说了IE的事件处理方式是bubble up,那么蓝色span截获绿色和红色regions中的onmouseover似乎是对的。可是对于蓝色span来说,这些被多余触发的onmouseover事件其实是不被期望的。IE没有做这个过滤,不知道是出于什么目的,不过我们可以自己在脚本中过滤掉这样的useless事件,有时这些事件很可能会干扰我们做精确的对蓝色span进行事件控制。假设蓝色span的onmouseover事件handler为isAbsoluteMoveOver,代码如下:
2{
3 if ( event )
4 {
5 var tagName = elmt.tagName;
6 var to = FindParentElement(event.toElement, tagName);
7 var from = FindParentElement(event.fromElement, tagName);
8 if ( elmt === to && from === to )
9 {
10 return false;
11 }
12 }
13 return true;
14}
这时只有在鼠标移入或移出蓝色span时,isAbsoluteMoveOver才返回true!
注:FindParentElement参看《设计有复杂客户端Script的服务器控件》。
posted on 2005-04-27 22:58 birdshome 阅读(2781) 评论(1) 编辑 收藏 举报