JS当中,mouseover和mouseout多次触发事件,不光是冒泡会产生,就是不冒泡,在一定条件下 ,也会产生多次触发事件;

例如下面的结构的情况下,我在class="ceng_up feature_tips"这个层上加这两个事件,就会多次触发mouseover和mouseout而不断的交替事件。

    <div id="tip_popu">
<!--浮动层-->
<div class="ceng_up feature_tips" style="top:4px; left:9px;">
<div class="top_feature"><div class="inner_text"><img src="/themes/default/images/icon.gif"><a href="#" class="em_a">武林英雄</a></div><div class="jishu">5426</div></div>
<div class="xiaceng">
<a class="c_1" href="#"></a>
<a class="c_2" href="#"></a>
<a class="c_3" href="#" title="活动公告"></a>
<div class="benzhou">本周<font color="#FF0000">+5%</font></div>
</div>
</div>
<div style="top:35px; left:239px; " class="ceng_down feature_tips">
<div class="top_feature"><div class="inner_text"><img src="/themes/default/images/icon.gif"><a href="#" class="em_a">武林英雄</a></div><div class="jishu">5426</div></div>
<div class="xiaceng">
<a href="#" class="c_1"></a>
<a href="#" class="c_2"></a>
<a title="活动公告" href="#" class="c_3"></a>
<div class="benzhou">本周<font color="#3A9B00">-9%</font></div>
</div>
</div>
</div>

开始是搞了好久,都没有找到适合的方法处理这个问题,最后终于在一个BLOG上看到这样的一个说法,终于把这个问题解决了;

下面是那个BLOG的原话,哥们直接复制过来了,加的颜色区分一下:

在用 到mouseover和mouseout事件来作为事件触发的条件,但是如果我们用做触发的元素内部有其他的元素的时候当鼠标移上的时候会反复的触发 mouseover和mouseout事件。因为内部元素在鼠标移上的时候会向它的父对象派发事件,所以外面元素相当于也触发了mouseover 事件。

为了阻止 mouseover和mouseout的反复触发,这里要用到event对象的一个属性relatedTarget,这个属性就是用来判断 mouseover和mouseout事件目标节点的相关节点的属性。简单的来说就是当触发mouseover事件时,relatedTarget属性代 表的就是鼠标刚刚离开的那个节点,当触发mouseout事件时它代表的是鼠标移向的那个对象。由于MSIE不支持这个属性,不过它有代替的属性,分别是 fromElement和toElement。

有了这个属性,我们就能够清楚的知道我们的鼠标是从哪个对象移过来,又是要移动到哪里去了。这样我们就能够通过判断这个相关联的对象是否在我们要触发事件的对象的内部,或者是不是就是这个对象本身。通过这个判断我们就能够合理的选择是否真的要触发事件。

这里我们还用到了一个用于检查一个对象是否包含在另外一个对象中的方法,contains方法。MSIE和FireFox分别提供了检查的方法,这里封装了一个函数。

function contains(parentNode, childNode) {
if (parentNode.contains) {
return parentNode != childNode && parentNode.contains(childNode);
} else {
return !!(parentNode.compareDocumentPosition(childNode) & 16);
}
}

这个函数用于检查一个对象是否被包含在我们的触发对象里面。

下面就是我们的重点了,我封装了一个用于检查鼠标是否真正从外部移入或者移出对象的函数checkHover(e,target),这个函数需要传入当前的事件对象和目标对象。

function checkHover(e,target){
if (getEvent(e).type=="mouseover") {
return !contains(target,getEvent(e).relatedTarget||getEvent(e).fromElement) && !((getEvent(e).relatedTarget||getEvent(e).fromElement)===target);
} else {
return !contains(target,getEvent(e).relatedTarget||getEvent(e).toElement) && !((getEvent(e).relatedTarget||getEvent(e).toElement)===target);
}
}function getEvent(e){
return e||window.event;
}

函数里面用到的getEvent()函数用于在MSIE或者FF下返回一个可用的event对象,这里你可以自己封装成别的函数。

函数的逻辑很简单,首先判断事件的类型,这个主要是为了迁就MSIE,当是 mouseover的时候relatedTarget在MSIE下应该是 fromElement,而mouseout则应该返回toElement,当然在FF下面就好办了,都是同一个属性relatedTarget。首先判 断我们的relatedTarget是否在目标对象的内部,如果是的话则直接返回假如果不在内部的话则判断是否是目标对象本身,如果是的话返回假,要是两 种情况都不成立则返回真。

到这里我们的主要工作做完了,有了这个函数我们在进行编程的时候只要在mouseover或者mouseout事件内部先检查一下,再进行下一步操作就能轻松实现hover的效果。

myElement.onmouseover=function(e){
if(checkHover(e,this)){
do someting...
}
}
myElement.onmouseout=function(e){
if(checkHover(e,this)){
do someting...
}
}

下面的代码,则是哥们自己写的代码部分,也贴出来,供大家参考(基于jquery):

    //取得当前窗口的事件
var e = window.event;
$('.con_yx ul li img').live(
'mouseover',
function(e) {
if(checkHover(e,this)){
var con_yx = $('.con_yx');
var index = con_yx.index($(this).parent().parent().parent());// 100px;
$('#index_val').val(index);
var currentspan = $(this).parent().find('span');// down
var position = $(this).offset();
if (currentspan.hasClass('up')) {
$(this).parent().find('img,.em_a').clone().appendTo('.ceng_up .inner_text');
$('.ceng_up').css('top', (position.top - 5));
$('.ceng_up').css('left', (position.left - 5));
$('.ceng_up').css('z-index',9999);
$('.ceng_down').hide();
$('.ceng_up').show();
} else {
$(this).parent().find('img,.em_a').clone().appendTo('.ceng_down .inner_text');
$('.ceng_down').css('top', (position.top - 5));
$('.ceng_down').css('left', (position.left - 5));
$('.ceng_down').css('z-index',9999);
$('.ceng_up').hide();
$('.ceng_down').show();
}
}
});
//鼠标移除层区域后,触发mouseout事件,把整个层隐藏
$('.ceng_up,.ceng_down').live('mouseout', function(e) {
if(checkHover(e,this)){
$(this).find('.inner_text').html('');
$(this).hide();
}
}); /**
* 下面是一些基础函数,解决mouseover与mouserout事件不停切换的问题(问题不是由冒泡产生的)
*/
function checkHover(e, target) {
if (getEvent(e).type == "mouseover") {
return !contains(target, getEvent(e).relatedTarget
|| getEvent(e).fromElement)
&& !((getEvent(e).relatedTarget || getEvent(e).fromElement) === target);
} else {
return !contains(target, getEvent(e).relatedTarget
|| getEvent(e).toElement)
&& !((getEvent(e).relatedTarget || getEvent(e).toElement) === target);
}
} function contains(parentNode, childNode) {
if (parentNode.contains) {
return parentNode != childNode && parentNode.contains(childNode);
} else {
return !!(parentNode.compareDocumentPosition(childNode) & 16);
}
}
//取得当前window对象的事件
function getEvent(e) {
return e || window.event;
}

js当中mouseover和mouseout多次触发(非冒泡)的更多相关文章

  1. mouseover和mouseout多次触发解决方法(兼容ie和firefox)(转)

    在用到mouseover和mouseout事件来作为事件触发的条件,但是如果我们用做触发的元素内部有其他的元素的时候当鼠标移上的时候会反复的触发mouseover和mouseout事件,如导致菜单闪烁 ...

  2. jq:mouseover和mouseout多次触发解决办法

    区别: mouseover与mouseenter 不论鼠标指针穿过被选元素或其子元素,都会触发 mouseover 事件. 只有在鼠标指针穿过被选元素时,才会触发 mouseenter 事件. mou ...

  3. mouseover和mouseout事件在鼠标经过子元素时也会触发

    JavaScript的mouseover和mouseout事件,在绑定元素内部有子元素的情况下, 经过绑定元素时会多次触发mouseover和mouseout事件. jQuery解决办法: jquer ...

  4. mouseover和mouseout、mouseenter和mouseleave

    又一个傻傻分不清楚的东东~ 现实真是一个问题天天有的世界~本以为我对js中的事件还是比较了解的,对于早就接触的mouse事件,更是觉得得心应手了~但是现实却给了我一记重拳! 我自身工作中遇到的犯二的故 ...

  5. jQuery-使用hover(fn,fn)函数监听mouseover和mouseout两个事件

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  6. jQuery mouseove和mouseout事件不断触发

    关于锋利的jQuery第三章结尾提示图片效果(鼠标放在图片上会出现一个大图跟随鼠标移动)实现时mouseove和mouseout事件不断触发的问题 html <ul class="bo ...

  7. mouseover和mouseout事件引发的BUG-解决方法

    mouseover和mouseout引发的BUG原由 当给一个元素添加mouseover或mouseout事件,这个元素还有子元素. 由于子元素的事件冒泡,鼠标移入或移出子元素都会触发事件. 解决的方 ...

  8. 鼠标 mouseover和mouseout事件

    在div内想实现鼠标移入移出效果,最开始的时候是用了jquery的mouseout和mouseover事件来实现的, $('.product).mouseover(function(){ …… }). ...

  9. mouseover、mouseout,mouseenter、mouseleave区别

    心情压抑的一天,我想好好的. mouseover与mouseenter 不论鼠标指针穿过被选元素或其子元素,都会触发 mouseover 事件. 只有在鼠标指针穿过被选元素时,才会触发 mouseen ...

随机推荐

  1. 洛谷P3384【模板】树链剖分

    题目描述 如题,已知一棵包含\(N\)个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作\(1\): 格式: \(1\) \(x\) \(y\) \(z\) 表示将树从\(x\ ...

  2. 如何理解javascript中的同步和异步

    javascript语言是一门“单线程”的语言,不像java语言,类继承Thread再来个thread.start就可以开辟一个线程,所以,javascript就像一条流水线,仅仅是一条流水线而已,要 ...

  3. mathjax;latex

    \lfloor $\lfloor$ \rfloor $\rfloor$ \sum_{i=1}^{n} $\sum_{i=1}^{n}$ \mu $\mu$ \mid $\mid$ \Leftright ...

  4. 【ACM】一种排序

    一种排序 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 现在有很多长方形,每一个长方形都有一个编号,这个编号可以重复:还知道这个长方形的宽和长,编号.长.宽都是整数 ...

  5. (转)linux内核参数注释与优化

    linux内核参数注释与优化 原文:http://blog.51cto.com/yangrong/1321594 http://oldboy.blog.51.cto.com/2561410/13364 ...

  6. Python 将IP转换为int

    import socket import struct if __name__ == '__main__': ip = '127.0.0.1' int_ip = struct.unpack('!I', ...

  7. [转]gbk和utf8的区别

    转自:百度经验 GBK编码:是指中国的中文字符,其它它包含了简体中文与繁体中文字符,另外还有一种字符“gb2312”,这种字符仅能存储简体中文字符. UTF-8编码:它是一种全国家通过的一种编码,如果 ...

  8. ACdream 1427—— Nice Sequence——————【线段树单点更新,区间查询】

    Nice Sequence Time Limit: 4000/2000MS (Java/Others)    Memory Limit: 128000/64000KB (Java/Others) Su ...

  9. 开始使用JQuery 方法

    使用jQuery需要3个基本步骤: 1. 下载jQuery.js并保存在网页可以存取的位置.下载链接:dowload 2. 在HTML的head里引用jQuery.js 3. 运用jQuery的方法 ...

  10. android-上下文菜单的创建 - 随心

    //Menu设置//覆盖两个方法onCreateOptionsMenu(Menu menu).onOptionsItemSelected(MenuItem Item)//onCreateOptions ...