一、(JS)JS中鼠标事件-mouseenter、mouseleave和mouseover、mouseout区别

news2024/11/14 10:53:43

 一、单个元素下mouseenter、mouseleave和mouseover、mouseout没有区别

我们先来一个demo,设置一个div

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      width: 200px;
      height: 200px;
      background-color: pink;
    }
  </style>
</head>

<body>

  <div class="box"></div>

  <script>

    var boxEl = document.querySelector(".box")

    // 第一组
    boxEl.onmouseenter = function () {
      console.log("onmouseenter");
    }
    boxEl.onmouseleave = function () {
      console.log("onmouseleave");
    }
    

    // 第二组
    boxEl.onmouseover = function () {
      console.log("onmouseover");
    } 
    boxEl.onmouseout = function () {
      console.log("onmouseout");
    }

  </script>

</body>

</html>

我们看下鼠标移动上去然后离开的反应:如图展示,

得出结论:单个元素不存在嵌套的情况下,两者是没有区别的。

二、嵌套元素下mouseenter、mouseleave和mouseover、mouseout的区别

(1)案例一:onmouseenter、onmouseleave进入子元素依然属于在父级元素内,没有任何反应。

我们在div里面添加一个span,并设置一个flex布局,从而给span设置宽高。

我们先把onmouseover和onmouseout注释掉,只看onmouseenter和onmouseleave的表现

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 200px;
      height: 200px;
      background-color: pink;
    }

    span {
      width: 100px;
      height: 100px;
      background-color: red;
    }
  </style>
</head>

<body>

  <div class="box">
    <span></span>
  </div>

  <script>

    var boxEl = document.querySelector(".box")

    // 第一组
    boxEl.onmouseenter = function () {
      console.log("onmouseenter");
    }
    boxEl.onmouseleave = function () {
      console.log("onmouseleave");
    }


    // 第二组
    // boxEl.onmouseover = function () {
    //   console.log("onmouseover");
    // }
    // boxEl.onmouseout = function () {
    //   console.log("onmouseout");
    // }

  </script>

</body>

</html>

onmouseenter和onmouseleave在嵌套元素的表现:

当鼠标移动到粉色区域的时候,也触发了onmouseenter事件,

当鼠标从粉色区域(div元素)移动到红色区域(span元素)的时候,没有触发onmouseenter事件,

得出结论:进入子元素依然属于在该元素内,没有任何反应。


(2)案例二:onmouseenter、onmouseleave不支持冒泡

那我们来只监听span的鼠标事件试试看

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 200px;
      height: 200px;
      background-color: pink;
    }

    span {
      width: 100px;
      height: 100px;
      background-color: red;
    }
  </style>
</head>

<body>

  <div class="box">
    <span></span>
  </div>

  <script>

    var boxEl = document.querySelector(".box")
    var spanEl = document.querySelector("span")

    // 第一组
    // boxEl.onmouseenter = function () {
    //   console.log("onmouseenter");
    // }
    // boxEl.onmouseleave = function () {
    //   console.log("onmouseleave");
    // }

    spanEl.onmouseenter = function () {
      console.log("span onmouseenter");
    }
    spanEl.onmouseleave = function () {
      console.log("span onmouseleave");
    }


    // 第二组
    // boxEl.onmouseover = function () {
    //   console.log("onmouseover");
    // }
    // boxEl.onmouseout = function () {
    //   console.log("onmouseout");
    // }

  </script>

</body>

</html>

onmouseenter和onmouseleave在嵌套元素的表现:

当鼠标移动到粉色区域的时候,没有触发了onmouseenter事件,

当鼠标移动到红色区域的时候,触发了onmouseenter事件,

得出结论:onmouseenter、onmouseleave不支持冒泡

(3)案例一和案例二的总结

  • onmouseenter、onmouseleave不支持冒泡
  • onmouseenter、onmouseleave进入子元素依然属于在父级元素内,没有任何反应。

(4)案例三:onmouseover、onmouseout总结

代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 200px;
      height: 200px;
      background-color: pink;
    }

    span {
      width: 100px;
      height: 100px;
      background-color: red;
    }
  </style>
</head>

<body>

  <div class="box">
    <span></span>
  </div>

  <script>

    var boxEl = document.querySelector(".box")
    var spanEl = document.querySelector("span")

    // 第一组
    // boxEl.onmouseenter = function () {
    //   console.log("box onmouseenter");
    // }
    // boxEl.onmouseleave = function () {
    //   console.log("box onmouseleave");
    // }

    // spanEl.onmouseenter = function () {
    //   console.log("span onmouseenter");
    // }
    // spanEl.onmouseleave = function () {
    //   console.log("span onmouseleave");
    // }


    // 第二组
    boxEl.onmouseover = function () {
      console.log("onmouseover");
    }
    boxEl.onmouseout = function () {
      console.log("onmouseout");
    }

  </script>

</body>

</html>

表现:

当鼠标移动到粉色区域的时候,console.log打印了onmouseover

当鼠标从粉色区域移动到红色区域的时候,console.log打印了onmouseover和onmouseout,说明什么?说明鼠标进入子元素后,告诉我们从父元素离开了,并且span子元素产生了一个事件,又冒泡给div父元素了。

得出结论:

  • 支持冒泡
  • 进入元素的子元素时
    • 先调用父元素的mouseout
    • 再调用子元素的mouseover
    • 因为支持冒泡,所以会将mouseover传递到父元素中

 三、区别

onmouseenter、onmouseleave

  • 不支持冒泡
  • 进入子元素依然属于在父级元素内,没有任何反应。

onmouseover、onmouseout

  • 支持冒泡
  • 进入元素的子元素时
    • 先调用父元素的mouseout
    • 再调用子元素的mouseover
    • 因为支持冒泡,所以会将mouseover传递到父元素中

四、案例应用

(1)案例练习一:有一个div,里面有3个button按钮,鼠标移动到哪个按钮上面,就给我console.log对应的元素里面的文本。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      width: 300px;
      height: 300px;
    }

    .box button {
      height: 50px;
    }
  </style>
</head>

<body>
  <div class="box">
    <button>删除</button>
    <button>新增</button>
    <button>搜索</button>
  </div>

</body>

</html>

方案一:监听的本身就是button元素(onmouseover、onmouseenter都可以,这里没区别)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      width: 300px;
      height: 300px;
    }

    .box button {
      height: 50px;
    }
  </style>
</head>

<body>
  <div class="box">
    <button>删除</button>
    <button>新增</button>
    <button>搜索</button>
  </div>

  <script>

    // 1. 方案一:监听的本身就是button元素
    var btnEls = document.querySelectorAll("button")
    for (var btnEl of btnEls) {
      btnEl.onmouseover = function () {
        // 这里不能直接用 btnEl.textContent去拿文本,因为这个时候 btnEl已经执行变成第三个button元素了.
        // 在你的代码中,事件处理函数 btnEl.onmouseover 中的 console.log(btnEl.textContent) 会一直输出 "搜索",而不是对应的按钮文本,是因为在 for...of 循环中使用了 var 声明变量 btnEl,导臨了变量提升的问题。这导致在循环结束后,btnEl 指向最后一个按钮元素,即 "搜索" 按钮。
        // console.log(btnEl.textContent);
        console.log(event.target.textContent);
      }
    }

  </script>

</body>

</html>

弊端:循环的时候,这里创建了三个函数。

怎么优化一下?见方案二

方案二: 事件委托

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      width: 300px;
      height: 300px;
    }

    .box button {
      height: 50px;
    }
  </style>
</head>

<body>
  <div class="box">
    <button>删除</button>
    <button>新增</button>
    <button>搜索</button>
  </div>

  <script>

    // 1. 方案一:监听的本身就是button元素
    var btnEls = document.querySelectorAll("button")
    // for (var btnEl of btnEls) {
    //   btnEl.onmouseover = function () {
    //     // 这里不能直接用 btnEl.textContent去拿文本,因为这个时候 btnEl已经执行变成第三个button元素了.
    //     // 在你的代码中,事件处理函数 btnEl.onmouseover 中的 console.log(btnEl.textContent) 会一直输出 "搜索",而不是对应的按钮文本,是因为在 for...of 循环中使用了 var 声明变量 btnEl,导臨了变量提升的问题。这导致在循环结束后,btnEl 指向最后一个按钮元素,即 "搜索" 按钮。
    //     // console.log(btnEl.textContent);

    //     console.log(event.target.textContent);
    //   }
    // }

    // 2. 方案二:事件委托
    // var boxEl = document.querySelector(".box")
    // boxEl.addEventListener("click", function (event) {
    //   if (event.target != boxEl) {
    //     console.log(event.target.textContent);
    //   }
    // }, true)

    var boxEl = document.querySelector(".box")
    // boxEl.addEventListener("mouseenter", function (event) {
    //   if (event.target != boxEl) {
    //     console.log(event.target.textContent);
    //   }
    // }, true)
    boxEl.addEventListener("mouseover", function (event) {
      if (event.target != boxEl) {
        console.log(event.target.textContent);
      }
    })



  </script>

</body>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2129610.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

INIC6081量产工具下载,initio6081开卡软件分享

国内固态硬盘常用&#xff0c;且有量产工具流传出来的主控厂商包括慧荣、群联、点序、英韧、得一微、瑞昱、联芸、迈威、国科、华澜微等等。 每个主控需要用各自对应的量产工具&#xff0c;不同的量产工具支持的闪存颗粒也有差异&#xff0c;因此要根据固态硬盘实际的主控型号…

基于SSM的酒店客房管理系统+LW示例参考

系列文章目录 1.基于SSM的洗衣房管理系统原生微信小程序LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统LW参考示例 3.基于SpringBootVue的企业人事管理系统LW参考示例 4.基于SSM的高校实验室管理系统LW参考示例 5.基于SpringBoot的二手数码回收系统原生微信小程序LW参考示…

Visual Studio 设置文件默认编码格式、行尾符等

文章目录 1.命令方式2.EditorConfig配置 1.命令方式 2.EditorConfig配置 微软官方文档 使用EditorConfig方式配置&#xff0c;无需Visual Studio软件自带对EditorConfig的支持&#xff0c;无需插件 将下面.editorconfig文件放在项目根目录下 root true # 所在目录是根目录…

基于SSM的二手交易管理系统的设计与实现 (含源码+sql+视频导入教程+文档)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的二手交易管理系统1拥有两种角色 管理员&#xff1a;商品管理、订单管理、充值管理、用户管理等用户&#xff1a;发布商品、查看闲置、充值账户、查看所有订单、发布求购信息、修…

今年白银市场的供需关系矛盾

自从2020年以来&#xff0c;白银手持连续4年都出现了供需缺口&#xff0c;预计今年的供需缺口将进一步扩大。2015年以来&#xff0c;白银总产量始终维持10亿盎司水平上下波动&#xff0c;2015~2023年的年均复合增速在0.4%&#xff0c;预计2024年的产量将下降1%。矿产银的产量从…

day-54 求出最多标记下标

思路 假设nums的长度为len&#xff0c;则返回数最大最大为&#xff08;len/2&#xff09;*2,所以可以将数组分为两部分&#xff0c;[0(len-1)/2]为一部分&#xff0c;[(len-1&#xff09;/2len-]为第二部分 解题过程 指针right从第二部分从右向左开始遍历&#xff0c;指针left…

Tensorboard 基础与使用-——界面介绍

在导入运行tensorboard得到一个event file文件。 tensorboard基本原理是这样的 python代码中将可视化的数据记录到event file中&#xff0c;保存至硬盘 采用tensorboard对event file文件进行读取&#xff0c;并在web端进行可视化 指令启动&#xff1a; tensorboard --logdir…

大数据Flink(一百一十七):Flink SQL的窗口操作

文章目录 Flink SQL的窗口操作 一、窗口的概述 二、Group Windows 1、​​​​​​​滚动窗口&#xff08;TUMBLE&#xff09; 2、​​​​​​​​​​​​​​滑动窗口&#xff08;HOP&#xff09; 3、​​​​​​​​​​​​​​Session 窗口&#xff08;SESSION&am…

军事目标无人机视角检测数据集 3500张 坦克 带标注voc

数据集概述 该数据集包含3500张无人机拍摄的图像&#xff0c;主要用于坦克目标的检测。数据集已经按照VOC&#xff08;Visual Object Classes&#xff09;标准进行了标注&#xff0c;适用于训练深度学习模型&#xff0c;特别是物体检测模型。 数据集特点 目标明确&#xff1…

通信工程学习:什么是GFP通用成帧规范

GFP&#xff1a;通用成帧规范 GFP通用成帧规范&#xff08;Generic Framing Procedure&#xff09;是一种先进的数据业务适配的通用协议和映射技术&#xff0c;由国际电联ITU-T的G.7041标准定义。该技术旨在透明地将各种不同物理层或逻辑链路层信号适配进入SDH&#xff08;同步…

C语言初识编译和链接

目录 翻译环境和运行环境编译环境预编译编译词法分析语法分析语义分析 汇编 链接运行环境 翻译环境和运行环境 在ANSI C的任何⼀种实现中&#xff0c;存在两个不同的环境。 第1种是翻译环境&#xff0c;在这个环境中源代码被转换为可执⾏的机器指令&#xff08;⼆进制指令&…

【Vue】1.v-指令、computed、watch

1 Vue 实例 注&#xff1a;此文件是 vue 根实例&#xff0c;data 可以 是一个对象 即 data:{ } 但是在其他 .vue 组件文件中&#xff0c;data 必须 是一个函数&#xff0c;返回一个新的对象&#xff0c;以避免多个组件实例之间的数据相互干扰 即 data(){ } <!DOCTYPE html&g…

前端正确设置资源上下文路径ContextPath(发布目录outDir 、公共基础路径),保证打包部署后站点能正常加载资源。

文章目录 引言I 处理资源上下文路径ContextPathjavascript对象获取上下文路径使用`./` 加载资源文件Vite 的basepublicPath是webpack部署应用包时的基本 URLII 知识扩展:URL的识别2.1 标准的链接格式2.2 URL中的?涵义2.3 URL中的&涵义2.4 传参III #fragment3.1为网页位置…

Vue2使用Vue CLI学习笔记

Vue2构建项目分析 Vue学习官网 Vue CLI官方 # 全局安装&#xff0c;只要装一次&#xff0c;以管理员身份 npm install -g vue/cli # 查看脚手架工具版本 vue --version # 创建项目&#xff0c;注意路径&#xff0c;名称不能是中文 vue create my-project # 启动项目&#xff…

基于Ant-Design-Vue设计的配置化表单

适用vue 3.4 版本以上 在日常的前端开发中&#xff0c;表单开发必不可少&#xff0c;尤其是在遇到一些大型的复杂的表单&#xff0c;这往往会变成一个痛点。于是就想着开发一个可以list来配置的表单组件。 先上组件代码 <!-- 该组件 VUE 版本在 3.4 以上可使用--> <…

【AI绘画】Midjourney进阶:景别详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AI绘画 | Midjourney 文章目录 &#x1f4af;前言&#x1f4af;为什么要学习景别景别的作用景别应用实例 &#x1f4af;大景别&#x1f4af;远景特点提示词书写技巧测试 &#x1f4af;全景特点提示词书写技巧测试注意点 &#x1f…

ozon免费选品工具,OZON免费选品神器

在跨境电商的浩瀚海洋中&#xff0c;寻找那片属于自己的盈利蓝海&#xff0c;是每个商家梦寐以求的目标。随着俄罗斯电商市场的迅速崛起&#xff0c;Ozon平台以其庞大的用户基数和不断增长的市场份额&#xff0c;成为了众多跨境卖家眼中的“香饽饽”。然而&#xff0c;面对琳琅…

【渗透测试】——DVWA靶场搭建

&#x1f4d6; 前言&#xff1a;DVWA&#xff08;Damn Vulnerable Web Application&#xff09;是一个用于安全漏洞测试的 PHP/MySQL 网络应用&#xff0c;旨在为安全专业人士提供一个合法的环境&#xff0c;以测试他们的技能和工具&#xff0c;同时帮助 Web 开发者更好地理解 …

计算机的信息编码和基本运算(上)

大家好我是清墨&#xff0c;今天同同同样来分享一下笔记。 计算机的信息编码 计算机用二进制编码的方式来表示和存储信息&#xff0c;我们见到的信息&#xff08;文字、图片等&#xff09;都是经过转换处理的。 ASCII&#xff08;American Standard Code for Information Int…

[001-02-001]. 第07-02节:线程的创建与使用

我的后端学习大纲 我的Java学习大纲 1、方式1&#xff1a;继承Thread类&#xff1a; 1.1.实现步骤 1.创建一个继承于Thred()类的子类2.重写Thread类的run()3.创建Thread类的子类的对象4.通过这个对象去调用start()方法 在调用start方法时就做了两件事&#xff0c;分别是&…