javascript中onmouse事件在div中失效问题的解决方法

也就是说,移到对象的子对象上,也算onmouseout了。但这往往会达不到我们想要的预期效果。这是由于javascript自身的冒泡特性导致的(即在子元素上触发了事件,并冒泡到了父元素-堆栈后进先出算法)。今天在网上搜了一下,找了以下的解决办法(兼容IE和Firefox)。
在IE下解决问题很简单,用onMouseEnter、onMouseLeave来代替onMouseOver、onMouseOut就行了,他们的作用基本相同,但前者不会发生冒泡(如果用 jQuery的event事件,只要绑定mouseleave、mouseenter即可)。但firefox下并没有onMouseEnter、onMouseLeave这两个事件。那么只能使用纯js来解决IE及Firefox的兼容性问题了:
原理:通过判断触发onMouseOut事件后,鼠标到达的元素是不是包含在父元素信息栏(div)内,如果是就表示鼠标还在信息栏(div)上,则不隐藏。如果否就表示鼠标真的移出了信息栏(div),那么信息栏就要隐藏。


代码如下:

// 首先来获取触发onMouseOut事件的元素,IE下通过event的toElement属性来获得,firefox下通过event的relatedTarget属性来获得。
IE:event.toElement ,Firefox:event.relatedTarget(注意:Firefox下的event须通过在函数调用时传入,而IE下的event则可以直接通过window.event系统对象来获得)
// ① 接下来就是判断获取的元素是否是主体div的子元素(IE下可以通过元素的obj.contains(element)方法来判断,但Firefox下没有这个方法,所以需要给firefox定义元素的obj.contains()方法)。
代码如下:
if(typeof(HTMLElement)!="undefined") // 给firefox定义contains()方法,IE已经系统自带有这个方法了
{
HTMLElement.prototype.contains=function(obj) {
while(obj!=null&&typeof(obj.tagName)!="undefind") { // 通过循环对比来判断是不是obj的父元素
     if(obj==this) { return true; }
     obj=obj.parentNode;
   }
return false;
};
}
// ② 获取和判断搞定后,我们就可以通过判断IE和Firefox来针对处理了,通过navigator.userAgent来判断浏览器类型:
if(navigator.userAgent.indexOf("MSIE")>0) {
return "MSIE";
}
if(navigator.userAgent.indexOf("Firefox")>0){
return "Firefox";
}
// ③ 到此为止所有要解决的问题都得到了解决,当触发onMouseOut事件时,我们将针对不同的浏览器先获取鼠标到达的元素,然后通过判断该元素是否在信息栏(div)内,如果元素是子元素,那么不执行onMouseOut事件,反之则执行事件,隐藏信息栏,完成后的代码如下:
function hideMsgBox(theEvent){ //theEvent用来传入事件,Firefox的方式
  if (theEvent){
  var browser=navigator.userAgent; //取得浏览器属性
  if (browser.indexOf("Firefox")>0){ //如果是Firefox
   if (document.getElementById('MsgBox').contains(theEvent.relatedTarget)) {//如果是子元素
   return; //结束函数
}
}
if (browser.indexOf("MSIE")>0){ //如果是IE
if (document.getElementById('MsgBox').contains(event.toElement)) { //如果是子元素
return; //结束函数
}
}
}
/*要执行的操作(如:隐藏)*/
document.getElementById('MsgBox').style.display='none' ;
……
}
// ④ 在信息栏(Div)上设置onMouseOut=hideMsgBox(event)来调用。

另外,通过设置window.event.cancelBubble = true (IE) ,event.stopPropagation() event.preventDefault() (Firefox) 也可以解决问题,但是需要遍历所有子元素,影响效率,所以还是在触发onMouseOut事件时再进行上述判断分别处理比较合适。

(0)

相关推荐

  • JavaScript控制各种浏览器全屏模式的方法、属性和事件介绍

    复制代码 代码如下: // 判断各种浏览器,找到正确的方法function launchFullscreen(element) {  if(element.requestFullscreen) {    element.requestFullscreen();  } else if(element.mozRequestFullScreen) {    element.mozRequestFullScreen();  } else if(element.webkitRequestFullscree

  • 浅析JavaScript事件和方法

    单击一个超链接触发事件 1.用a标签的onclick <a href="#" onclick="js代码"> 这种写法呢,存在一种弊端,就是点击后会刷新一次页面,回到页面顶端. 想不刷新如何做的呢? 复制代码 代码如下: <a href="javascript:void(0)" onclick="js代码"> 2.#与javascript:void(0)的区别 超链接为"死链"时,使

  • javascript下给元素添加事件的方法与代码

    最简单的是这样: <input type="button" onclick="alert(this.value)" value="我是 button" /> 动态添加onclick事件: <input type="button" value="我是 button" id="bu"> <script type="text/javascript&quo

  • JavaScript调用Activex控件的事件的实现方法

    书写成这样: <SCRIPT type="text/javascript" FOR="activexID" EVENT="onXXXevent()" > // js 处理具体内容. </SCRIPT> 当acitveX控件 onXXXevent()事件被触发时,调用此方法. 如果一个半个的话还好说,几十个这样的函数,把我的页面占据的满满的.况且在VS2008中,"设置选定内容格式化"总是提示:"

  • javascript的onchange事件与jQuery的change()方法比较

    改变一下思路变成键盘按键事件,如下: <asp:TextBox ID="txtName" runat="server" onkeyup="fNameChange();"></asp:TextBox> 这里有一点毛病是,你复制粘贴的内容,无法触发这个事件.下面是相关的一些代码: 复制代码 代码如下: function fNameChange(){ if($('#txtName').val().length<6){ jQ

  • JavaScript window.document的属性、方法和事件小结

    javascript中window.document的属性.方法和事件的总结,有需要的朋友可参考一下本文章. 属性: Attributes 存储节点的属性列表(只读) childNodes 存储节点的子节点列表(只读) dataType 返回此节点的数据类型 Definition 以DTD或XML模式给出的节点的定义(只读) Doctype 指定文档类型节点(只读) documentElement 返回文档的根元素(可读写) firstChild 返回当前节点的第一个子节点(只读) Implem

  • javascript中onmouse事件在div中失效问题的解决方法

    也就是说,移到对象的子对象上,也算onmouseout了.但这往往会达不到我们想要的预期效果.这是由于javascript自身的冒泡特性导致的(即在子元素上触发了事件,并冒泡到了父元素-堆栈后进先出算法).今天在网上搜了一下,找了以下的解决办法(兼容IE和Firefox). 在IE下解决问题很简单,用onMouseEnter.onMouseLeave来代替onMouseOver.onMouseOut就行了,他们的作用基本相同,但前者不会发生冒泡(如果用 jQuery的event事件,只要绑定mo

  • php正则匹配html中带class的div并选取其中内容的方法

    本文实例讲述了php正则匹配html中带class的div并选取其中内容的方法.分享给大家供大家参考.具体分析如下: 先看一段html代码: 复制代码 代码如下: <div class="chartInfo">   <div class="line"></div>  <div class="tideTable">       <strong>潮汐表</strong>数据仅供参

  • spring boot 2.x html中引用css和js失效问题及解决方法

    在application.properties中配置了static的默认路径 我的static目录结构是这样的 index.html中这样引用css或者js文件,用到了th标签 html使用th标签需要先导入 以上这样配置好了之后发现网页的css和js果然加载出来了. 自定义拦截器失效 在自定义拦截器注册之后发现静态资源被拦截了,注释掉拦截器发现果然是拦截器的问题. 在注册方法上使用了excludePathPatterns()排除静态资源的拦截,发现该方法失效了,查看源码WebMvcConfig

  • javascript使用for循环批量注册的事件不能正确获取索引值的解决方法

    本文实例讲述了javascript使用for循环批量注册的事件不能正确获取索引值的解决方法.分享给大家供大家参考.具体分析如下: 可能不少朋友会遇到一个问题,那就是当使用for循环批量注册事件处理函数,然后最后通过事件处理函数获取当前元素的索引值的时候会失败,先看一段代码实例: 复制代码 代码如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name=&q

  • js中Number数字数值运算后值不对的解决方法

    问题: 37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数) 我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.08499999999998 怎么会这样,两个只有一位小数的数字相乘,怎么可能多出这么小数点出来. 我Google了一下,发现原来这是JavaScript浮点运算的一个bug. 比如:7*0.8 JavaScript算出来就是:5.6000000000000005 解决方法:网上找到了一些解决办法,就是重新写了一些浮点运算的函数. 下面就把这

  • AngularJS 中使用Swiper制作滚动图不能滑动的解决方法

    Swiper是目前较为流行的移动端触摸滑动插件,因为其简单好用易上手,受到很多前端开发者的欢迎. 今天在使用Swiper的时候遇到这个问题: 使用angularjs动态循环生成swiper-slide类,在swiper-wrapper里生成6个以上的滑动页,可是就是划不到第二页,尝试将longSwipesRatio的值修改到最小,仍然不起作用. <div class="swiper-wrapper" > <!-- =======循环部分======= --> &

  • 关于JS中setTimeout()无法调用带参函数问题的解决方法

    本文实例分析了JS中setTimeout()无法调用带参函数问题的解决方法.分享给大家供大家参考,具体如下: 解决方法:重写setTimeout() 方法,需要用到闭包函数.如下: var _st = window.setTimeout; window.setTimeout = function(fRef, mDelay){ if (typeof fRef == 'function') { var argu = Array.prototype.slice.call(arguments, 2);

  • js文件中直接alert()中文出来的是乱码的解决方法

    解决方法如下: 在这句语句上面加上echo "<meta http-equiv='Content-Type'' content='text/html; charset=utf-8'>"; 以上就是小编为大家带来的js文件中直接alert()中文出来的是乱码的解决方法全部内容了,希望大家多多支持我们~

  • python中print的不换行即时输出的快速解决方法

    关于Python2.x和3.x带来的print不换行的问题:昨天有发过推文,利用end = 定义,解决了横向的小问题,但是由于屏幕显示的问题,若字符串长度过大,则会引起不便.两个或多个print做分割的情况下,如何保持依然横向输出,一般的是在print尾部加上逗号(,)但是在3.x下,则不行,需要使用end = "(something)",some signs like , . ; 'also you can put a word or str in"". Exam

  • OpenCV中C++函数imread读取图片的问题及解决方法

    今天在用OpenCV实验Image Pyramid的时候发现一个奇怪的问题,就是利用C++函数imread读取图片的时候返回的结果总是空,而利用C函数cvLoadImage时却能读取到图像.代码如下: //环境:VS2010 + OpenCV 2.3.1 #include "stdafx.h" #include <cv.h> #include <highgui.h> #include <math.h> #include <stdlib.h>

随机推荐