js复习鼠标事件笔记

一、鼠标事件

dom3事件模型中与鼠标事件相关的事件共12种鼠标事件

  • 5个点击相关
  • 5个移动相关
  • 1个滚动
  • 1个选择事件

点击相关事件:

  • click

  • dblclick

  • contextmeun (次键点击)

  • mousedown

  • mouseup

移动相关

  • mousemove

  • mouseenter

  • mouseover

  • mouseleave

  • mouseout

滚动

  • wheel

选择

  • select

click 执行顺序

dblclick 执行顺序

二、relatedTarget

参考:https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/relatedTarget

定义:和事件相关的次要节点,如果存在返回节点,不存在返回null

target与relatedTarget总是相反的

与relatedTarget相关的事件,有以下8种:

  • focusin
  • focusout
  • mouseover
  • mouseout
  • mouseenter
  • mouseleave
  • dragenter
  • dragexit

###(1) mouseover与mouseenter(mouseout和mouseleave同理)的区别

[1]mouseover:

  • 特征:从事件节点进入其子节点也会触发事件,会向父节点冒泡
  • target: 移入进入节点
  • relatedTarget: 移入时离开的节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
#container {
width: 200px;
height: 200px;
background-color: blue;
}

#child {
width: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<div id="container" onmouseover="handleMouseover(event)">
<div id="child">sddddd</div>
</div>
<script>
function handleMouseover(e) {
console.log(e);
}
</script>
</body>
</html>

[2]mouseenter:

  • 特征:从事件节点进入其子节点也会不会触发事件,不会向父节点冒泡
  • target: 移入进入节点
  • relatedTarget: 移入时离开的节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
#container {
width: 200px;
height: 200px;
background-color: blue;
}

#child {
width: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<div id="container" onmouseenter="handleMouseEnter(event)">
<div id="child">sddddd</div>
</div>
<script>
function handleMouseEnter(e) {
console.log(e); // 进入事件节点的子阶段不会触发
}
</script>
</body>
</html>

[3]通过mouseover模拟mouseenter:

(1) 模拟实现核心思路:

只处理从外层移入的事件

(2) 拆分步骤:

mouseOver伴随以下几种情况

  • 外层节点移入事件节点 (relatedTarget: 外层节点)

  • 事件节点往子节点移入

    • 事件节点往子节点移入 (relatedTarget: 事件节点)
    • 事件节点的子节点往其他子节点移入 (relatedTarget: 事件节点子节点)

(3)因此模拟处理的关键:

判断次要节点不是 本身也不是其子节点

(4)是否可以只判断,非自身节点

不能,若只判断判断次要节点不是本身,绝大多数情况可以解决但是一个前提是需要事件节点与子节点间有空间才可以判断,如果没有空间可能是更上一层的节点

(5)是否可以通过阻止子节点冒泡来解决

不能,只能解决子节点之间移动的问题,不能解决子节点往事件节点上的触发

(6)是否可以通过事件流的方式解决

不能,通过addEventListener解决: 无效(会产生新的mouseover,有一个完整的事件流)、

(2)鼠标事件对应的事件处理程序

参考:https://developer.mozilla.org/zh-CN/docs/Web/API/MouseEvent

[1] 鼠标事件相关属性

可以大致分为三类:

  • 位置相关

    • screenX (相对屏幕位置):他提供了鼠标相对于屏幕坐标系的水平偏移量
    • clientX (相对可是区域位置,浏览器窗口)
    • pageX (相对于html文档) (非标准属性)兼容:pageX = clientX + scrollLeft + clientLeft
    • offesetX: 鼠标在的位置与触发元素相距的距离,以content为参考点(ie属性非标准,但浏览器打多实现,基本通用)
    • movementX : 与mousemove搭配,两个连续的mousemove相隔的距离 (ie不支持,现代浏览器支持)
  • 键盘相关

    • cotrrolKey:
      点鼠标时,有没有按住cotrrol
    • shiftKey:
      点击点鼠标时,有没有按住shift
    • altKey:
      点击点鼠标时,有没有按住alt
    • metaKey: (win键 command键)
    • button:-1(没有按键)鼠标移动 0 (主键) 1 (辅助键) 2 (次键)
    • buttons: 同时按下两个键,数字可能会变,3位2进制值 1 左 2 右 4 中
      举例: 左中:5
[2]位置相关以及键盘相关注意事项

(1)强调 click只是主键点击

(2)其他键可以通过 mousedown mouseup

(3)preventDefalt可以注销contextmenu

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.context {
background-color: pink;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div class="context" oncontextmenu="handleOnContextmenu(event)">
21321
</div>
<script>
function handleOnContextmenu(e) {
e.preventDefault(); //阻止默认右键菜单
console.log('弹出自定义菜单');
}
</script>
</body>
</html>

当滚动鼠标滚轮或操作其它类似输入设备时会触发滚轮事件。滚轮事件替换了已被弃用的非标准mousewheel事件。

(1)mousewheel事件

  • 可以冒泡冒泡到document
  • wheeldelta: 是一个整值120的倍数 上滚120倍数 下滚是-120倍数 是滚动调的方向,一般只关心正数还是负数
  • mousewheel,documentmouse
    存在detail wheelDelta 1的倍数 新版正3 -3,和标准相反
  • 标准版本weel事件(html5):大部分浏览器都支持
    deltaX: 变量增量 X 浏览器数值不同
    deltaY:变量增量 Y 浏览器数值不同
    deltaZ: 变量增量 Z 浏览器数值不同
[4]滚动鼠标事件注意点:
  • 要根据实际客户需求调研,客户版本(mdn文档)
  • wheeldelta 不一定是整数倍,线性滚轮鼠标不一定正数,mac触控板也模拟鼠标滚轮,就有可能是3的倍数(可能会触发几十次,并且可能有动画过度,wheelDealte可能还会继续改变)
  • 不要相信wheeldelta的值
  • 极限情况:wheeldelta(通常是抛物线曲线)会出现震动情况(一般是动画过程中旋转设备,切换屏幕)
  • 鼠标滚动事件和页面滚动事件无关 (触摸设备手指滑,pc拖拽滚动条也不会触发滚动事件,mac放大不会触发,mac和安卓 2手指手势会触发)
    只能通过滚轮或触控板触发
  • 滚动到页面顶部和底部后也会继续触发

(3)防抖函数与节流函数

只叙述概念,之后文章具体分析源码与原理

根本原理是通过时间戳控制

[1] 防抖函数

同一个时间处理,当超过设定时间后才触发,

核心实现思路:2个事件发生间隔小于某个时间点,推迟执行

[2] 节流函数

同一个事件处理,设定时间内只触发一次

核心实现思路:2个事件发生间隔大于某个时间点,就执行

Share