一、(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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值