当前位置: 首页 > article >正文

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

 一、单个元素下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.kler.cn/news/309788.html

相关文章:

  • 使用Redis实现用户关注博客的推模式
  • Go 交叉编译
  • Jenkins部署若依项目
  • 开源 AI 智能名片 S2B2C 商城小程序中的全渠道供应策略
  • 深度学习张量变换操作利器 einops 基础实践
  • 消息中间件有哪些常见类型
  • sql刷题常用函数
  • 微博计算架构实战
  • 【Android 13源码分析】WindowContainer窗口层级-1-初识窗口层级树
  • 【车载开发系列】ParaSoft单元测试环境配置(三)
  • 【原创】java+springboot+mysql高校社团网系统设计与实现
  • 【数据库】MySQL-基础篇-多表查询
  • 赋值运算符
  • 用Kimi输出流程图
  • MybatisPlus的一点了解
  • 深入Redis:分布式锁
  • [语言月赛 202408] 因友情而终结
  • 深圳国际VR/AR博览会圆满落下帷幕
  • 【C++ Primer Plus习题】16.8
  • yaml注入配置文件
  • 【ZYNQ】OV5640 图像采集与显示
  • 【Linux】权限理解(超详细)
  • 【与C++的邂逅】--- C++的IO流
  • sqlgun靶场训练
  • 【机器学习】--- 自然语言推理(NLI)
  • SPI软件模拟读写W25Q64
  • Qt常用控件——QLCDNumber
  • scantf
  • Linux--守护进程与会话
  • Java 中 List 常用类和数据结构详解及案例示范