javascript中mouseover和mouseout事件详解

2023-11-15

原文链接:http://blog.sina.com.cn/s/blog_468530a60101awlw.html

  与 mouseenter 事件不同,不论鼠标指针穿过被选元素或其子元素,都会触发 mouseover 事件。只有在鼠标指针穿过被选元素时,才会触发 mouseenter 事件。
  与 mouseout 事件不同,只有在鼠标指针离开被选元素时,才会触发 mouseleave 事件。如果鼠标指针离开任何子元素,同样会触发 mouseout 事件。

  解决两者的区别,看下面引用的例子:

  当为某个容器绑定了 onmouseover 或者onmouseout 事件时,如果这个容器中有其它元素节点,那么鼠标在内部移动时会频繁触发 onmouseover和onmouseout 事件。

  而我想要的效果是:事件仅在鼠标进入/离开元素区域触发一次,当鼠标在元素区域内部移动的时候不会触发。

  为什么会出现这个原因呢?其实是因为事件冒泡导致的。当鼠标移上或者移出容器中的子节点时,会分别触发mouseover和mouseout事件,紧随着dom树向上冒泡传递,直到被事件处理程序(监听器)捕获捕获或者冒泡到根节点(document或者window),也就是说事件会向它的父级对象派发。

  知道了问题产生原因,那么解决起来是不是也很简单呢?最初我想的是取消事件冒泡,使用event.cancelBubble = true(IE)和e.stopPropagation()(其它浏览器),但是简单测试后发现貌似没有什么效果,问题依旧,貌似冒泡停止不了,原因不明。(补充:我是测试将容器中的a链接节点取消冒泡,但是发现鼠标移上移下还会触发事件。a节点下还有span节点。难道要将容器中所有节点都取消冒泡才行?有心人可以测试,如果真的这样,那也太恶心了,要是N多的节点,难道都要停止冒泡下?)

  其实在IE下鼠标事件有个 mouseEnter 和 mouseLeave,这个就是移进和移处容器时触发一次,在内部移动则不会触发,遗憾的是只有IE支持。我们现在要做的就是“为非IE浏览器添加mouseEnter和mouseLeave支持”。

  我翻阅了百度最新开源的JS库tangram,看了里面的处理,发现貌似是单独处理了非IE浏览器下的事件,使用一个叫“baidu.event._eventFilter._crossElementBoundary(listener, e)”的方法修正mouseover和mouseout,然后封装了个mouseEnter和mouseLeave事件。

baidu.event._eventFilter._crossElementBoundary = function(listener, e){
    var related = e.relatedTarget,
        current = e.currentTarget;
    if(typeof related == 'undefined'){
        return listener.call(current, e);
      }
    // 如果current和related都是body,contains函数会返回false
    // Firefox有时会把XUL元素作为relatedTarget
    // 这些元素不能访问parentNode属性
    // thanks jquery & mootools
    //如果current包含related,说明没有经过current的边界
    //注:baidu.dom.contains是个定义的检测节点是否包含的函数,下面我会讲到
    if(related === false || current == related || related.prefix == 'xul' || baidu.dom.contains(current, related)){
         return ;
      }
    //调用执行
    return listener.call(current, e);
    };

  百度的方法我并不喜欢,首先它只对非IE浏览器进行了处理,当然,它又进行了封装,可以直接使用mouseEnter和mouseLeave;但是,我们做普通开发,没必要这么封装,我只是想要简单的去掉mouseover和mouseout的这个恼人特性。

  而jQuery则不是这么做的,它是直接对IE和其它所有浏览器下的mouseover和mouseout事件进行了修正。参考jQuery,我得到了我目前所有的代码。

  首先,介绍个判断节点对象是否包含的函数contains.

function contains(p,c){
    return p.contains ?
    p != c && p.contains(c) : !!(p.compareDocumentPosition(c) & 16);
}

  然后就是重点的了,这里我们在IE下用到了fromElement和toElement,这两个是IE下的鼠标移上去时和移出时的节点对象。

function fixedMouse(e,target){
    var related,
    type=e.type.toLowerCase();//这里获取事件名字
    if(type=='mouseover'){
        related=e.relatedTarget||e.fromElement
      }else if(type='mouseout'){
        related=e.relatedTarget||e.toElement
      }else return true;
      return related && related.prefix!='xul' && !contains(target,related) && related!==target;
}

  然后我们怎么用呢?比如在绑定事件时,

//addListener为封装的事件绑定函数
addListener(target,'mouseover',function(e){
    e=e||window.event;
    if(fixedMouse(e, target)){
    //do something
    }
},false);

  这样就会只在移入移出target节点时触发mouseover和mouseout了。

  当然,你也可以将上面的代码单独封装成mouseEnter和mouseLeave,这样可以以后调用时更好区别mouseover和mouseout。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

javascript中mouseover和mouseout事件详解 的相关文章

随机推荐

  • 论文笔记——HRFormer

    摘要 本文提出了一种高分辨率Transformer HRFomer 它在密集的预测任务中学习高分辨率表示 而原来的Vison Transformer则产生低分辨率表示 具有高内存和计算成本 作者利用了高分辨率卷积网络 HRNet 中引入的多
  • C#基础(字符串拼接)

    字符串拼接方式1 之前的算术运算符 只是用来数值类型变量进行数学运算的 而 string 不存在算术运算符 不能计算 但是可以通过 号来进行字符串拼接 用 号来进行字符串拼接 str str 456 复合运算符 str 1 4 true s
  • 群晖虚拟机部署线上恋爱网站

    文章目录 前言 1 安装网页运行环境 1 1 安装php 1 2 安装webstation 2 下载网页源码文件 2 1 访问网站地址并下载压缩包 2 2 解压并上传至群辉NAS 3 配置webstation 3 1 配置网页服务 3 2
  • 关于电子设计大赛

    一年一度的电子设计大赛选拔赛开始了 作为参加两年的选手还是很有感悟 下面我简单从电赛是什么和经验教训谈论一下 电赛全称全国大学生电子设计大赛 它国赛和省赛交叉进行 是衡量大学生电子设计能力的重要平台 也是用人单位评价别人的基础之一 比赛时间
  • SpringBoot接收前端参数json格式的五种方式

    import java util List import java util Map import org springframework web bind annotation RequestBody import org springf
  • 游戏开发 - 开发流程 - 收集

    1 应用场景 主要用于了解 掌握游戏开发的整个流程 2 学习 操作 1 文档阅读 复习课 带你梳理客户端开发的三个重点 极客时间 2 整理输出 2 1 游戏开发流程 参考 按照游戏开发中的三大模块策划 程序 美术 画了一个图 开发游戏的时候
  • 今天遇到了个问题我本想测试一下Java连接一下redis的,结果。。。。。。

    一开始写好了java程序结果idea连接云服务器上的redis报错 Failed to connect to any host resolved for DNS name 期初我以为是我的Jedis有问题或者是redis conf配置又或者
  • 人工智能数学基础:泰勒(Taylor)公式

    一 引言 对于一些较复杂的函数 为了便于研究 往往希望用一些简单的函数来近似表达 例如 当x gt 0时 sinx arcsinx tanx arctanx ln 1 x ex 1 x 由于用多项式表示的函数 只要对自变量进行有限次加 减
  • STM32发送单极性归零码驱动WS2812(二)

    STM32发送单极性归零码驱动WS2812 二 形容我的心情 二 旧事 重提 时间匆匆过去 也到了该着手准备毕业设计的阶段了 我早早就向老师确定了选题 我想做一个智能灯光控制系统 在灯光选型的问题上 我又想到了几个月前令我头疼好长时间的WS
  • 那些令人惊叹的 HTML、CSS、JavaScript 工具和库

    前端开发很奇妙 它入门很简单 但是想要成为大牛却很难 有太多的事情需要考虑 到处都有需要微调的地方 太多的细节处理才能保证让一切都刚刚好 幸运的是 开发者和设计师一直致力于为我们提供有用的工具和资源 来提高我们的技能 让我们做的更好 所以今
  • Linux安装Phantomjs

    PhantomJS是一个可编程的无头浏览器 无头浏览器 一个完整的浏览器内核 包括js解析引擎 渲染引擎 请求处理等 但是不包括显示和用户交互页面的浏览器 1 页面自动化测试 希望自动的登陆网站并做一些操作然后检查结果是否正常 2 网页监控
  • 机器学习中的流形学习算法 Manifold Learning

    1 流形学习概述 流形学习manifold learning 于2000年在Science杂志上首次提出 是一大类基于流形的框架 是机器学习 模式识别中的一种方法 在维数约简 降维 方面具有广泛的应用 它的主要思想是将高维的数据映射到低维
  • 最新视频/图集去水印/步数/王者战力/红包封面等小程序源码带流量主【源码+教程】

    免服务器域名 已测试 上传即可用带流量主功能 这套源码目前没在网上看到过几次 源码内附带教程 去水印支持快手抖音视频 图集其他平台自测 下载地址 最新视频 图集去水印 步数 王者战力 红包封面等小程序源码带流量主 源码 教程
  • tftp+Filezilla文件双向传输(1)-centos(VMware)-win10(host)

    目录 1 下载安装vsftpd tftp tftp server 2 配置服务 2 1 配置服务 修改文件 etc vsftpd conf 2 2 配置服务 守护进程 etc xinetd d tftp 2 3 配置服务 tftp服务器 2
  • 微信小程序的websocket使用stomp协议--简单实用的npm包

    需求背景 在公司实习期间 要求做一个小程序的websocket连接 用于设备的实时控制和状态查询 其中后端使用的是stomp协议 而微信小程序是不支持stomp协议的 但是当我知道的时候 后端已经全部调好只等我接入了 由于小程序的心跳机制和
  • BST插入(建立)、删除、查找和排序

    实验要求 设计BST 的左右链存储结构 并实现BST插入 建立 删除 查找和排序算法 实现折半查找算法 实验比较 设计并产生实验测试数据 考察比较两种查找方法的时间性能 并与理论结果进行比较 以下具体做法可作为参考 第1组测试数据 n 10
  • 关系代数的自然连接符号_数学——符号推演的艺术

    数学离不开各式各样的符号 数字如2 0 1 8 运算符如 等号 不等号 都是最常见的数学符号 其他语义复杂一些的数学符号有 sin 等等 这些有趣的符号可以用来表示各种具体或者抽象的数学概念 包括数学对象以及数学对象之间的相互关系 而数学活
  • 一、Linux命令行使用技巧

    一 Linux命令行使用技巧 1 新建笔记本 命令 lt gedit gt lt 空格 gt lt 文件名 gt 2 什么是Linux 操作系统 内核 kernel 相当于人的大脑 3 计算机五大组件 计算器 寄存器 控制器 输入设备 输出
  • 三进制计算机_计算机产业有望进入三进制时代:韩国研发出三进制半导体

    韩国一科研团队成功在大尺寸晶圆上实现了更节能的三元金属氧化物半导体 我们知道通常计算机是由一个个逻辑电路组成的 而逻辑电路一般只有接通和断开两种状态 所以计算机中的数据都是以二进制形式存在的 本质上来说计算机就是0和1 最早将二进制这一理念
  • javascript中mouseover和mouseout事件详解

    原文链接 http blog sina com cn s blog 468530a60101awlw html 与 mouseenter 事件不同 不论鼠标指针穿过被选元素或其子元素 都会触发 mouseover 事件 只有在鼠标指针穿过被