onmouseout的一些问题

前几天在项目里状态选择这个功能上遇到点麻烦。先描述一下问题:当用户点击状态后显示下拉菜单,若用户没有做出选择就移出菜单,则让菜单隐藏起来。这个很容易想到用onmouseout来解决,但事情没有这么简单,来看一下实例:

提示:你可以先修改部分代码再运行。

我们发现从一个子元素移到另一个子元素的时候就会触发onmouseout事件,并没有等鼠标离开整个菜单后隐藏。
为了看清楚问题,下面的代码用来显示获取触发onMouseOut事件的元素。

提示:你可以先修改部分代码再运行。


代码中relatedTarget事件属性返回与事件的目标节点相关的节点。对于 mouseover 事件来说,该属性是鼠标指针移到目标节点上时所离开的那个节点。对于 mouseout 事件来说,该属性是离开目标时,鼠标指针进入的节点。对于其他类型的事件来说,这个属性没有用。IE中使用toElement代替relatedTarget。
接下来判断获取的元素是否是子元素,IE下通过元素的contains(Element)方法可以判断,同样的firefox下没有这个方法,不过可以给firefox下的元素定义contains()方法来解决问题,代码如下:

当触发onMouseOut事件时我们针对不同的浏览器先获取鼠标到达的元素,然后通过判断该元素是否在下拉菜单内,如果元素是子元素,那么不执行onMouseOut事件,反之则执行事件,隐藏下拉菜单,完整代码如下:

提示:你可以先修改部分代码再运行。

/*—————————————- 20110617更新 —————————————-*/
近来又研究了下contains()方法,IE、Safari3及更高版本、Opera8及更高版本、Chrome都支持contains()方法。Firefox不支持此方法,但Firefox在DOM3级实现中提供了一个替代的compareDocumentPosition()方法(Opera9.5及更高版本也支持此方法)。这个方法用于确定两个节点之间的关系,返回一个表示该关系的位掩码(bitmask)。

掩 码 节点关系
1 无关(给定的节点不在当前文档中)
2 居前(给定的节点在DOM树中位于参考节点之前)
4 居后(给定的节点在DOM树中位于参考节点之后)
8 包含(给定的节点是参考节点的祖先)
16 被包含(给定的节点是参考节点的后代)

为模仿contains()方法,应该关注的是掩码16。来看下面例子:

执行结果result为20(表示“居后”的4加上表示“被包含”的16)。对掩码16执行按位操作会返回一个非零数值。
最后,我们的代码可以改用上面的方法来判断鼠标是否移出菜单:

提示:你可以先修改部分代码再运行。

参考资料:
contains http://msdn.microsoft.com/en-us/library/ms536377(VS.85).aspx
toElement http://msdn.microsoft.com/en-us/library/ms534684(v=vs.85).aspx
relatedTarget http://www.w3school.com.cn/htmldom/event_relatedtarget.asp
解决js中onMouseOut事件冒泡的问题:http://blog.163.com/ak_74a/blog/static/470404072008530105542228/
《javascript高级程序设计》

发表评论

电子邮件地址不会被公开。 必填项已用*标注