|
| 1 | +# MouseEvent 接口 |
| 2 | +## MouseEvent 接口概述 |
| 3 | + |
| 4 | +`MouseEvent`接口代表了鼠标相关的事件,单击(click)、双击(dblclick)、松开鼠标键(mouseup)、按下鼠标键(mousedown)等动作,所产生的事件对象都是`MouseEvent`实例。此外,滚轮事件和拖拉事件也是`MouseEvent`实例。 |
| 5 | + |
| 6 | +`MouseEvent`接口继承了`Event`接口,所以拥有`Event`的所有属性和方法。它还有自己的属性和方法。 |
| 7 | + |
| 8 | +浏览器原生提供一个`MouseEvent`构造函数,用于新建一个`MouseEvent`实例。 |
| 9 | + |
| 10 | +```javascript |
| 11 | +var event = new MouseEvent(type, options); |
| 12 | +``` |
| 13 | + |
| 14 | +`MouseEvent`构造函数接受两个参数。第一个参数是字符串,表示事件名称;第二个参数是一个事件配置对象,该参数可选。除了`Event`接口的实例配置属性,该对象可以配置以下属性,所有属性都是可选的。 |
| 15 | + |
| 16 | +- `screenX`:数值,鼠标相对于屏幕的水平位置(单位像素),默认值为0,设置该属性不会移动鼠标。 |
| 17 | +- `screenY`:数值,鼠标相对于屏幕的垂直位置(单位像素),其他与`screenX`相同。 |
| 18 | +- `clientX`:数值,鼠标相对于程序窗口的水平位置(单位像素),默认值为0,设置该属性不会移动鼠标。 |
| 19 | +- `clientY`:数值,鼠标相对于程序窗口的垂直位置(单位像素),其他与`clientX`相同。 |
| 20 | +- `ctrlKey`:布尔值,是否同时按下了 Ctrl 键,默认值为`false`。 |
| 21 | +- `shiftKey`:布尔值,是否同时按下了 Shift 键,默认值为`false`。 |
| 22 | +- `altKey`:布尔值,是否同时按下 Alt 键,默认值为`false`。 |
| 23 | +- `metaKey`:布尔值,是否同时按下 Meta 键,默认值为`false`。 |
| 24 | +- `button`:数值,表示按下了哪一个鼠标按键,默认值为`0`,表示按下主键(通常是鼠标的左键)或者当前事件没有定义这个属性;`1`表示按下辅助键(通常是鼠标的中间键),`2`表示按下次要键(通常是鼠标的右键)。 |
| 25 | +- `buttons`:数值,表示按下了鼠标的哪些键,是一个三个比特位的二进制值,默认为`0`(没有按下任何键)。`1`(二进制`001`)表示按下主键(通常是左键),`2`(二进制`010`)表示按下次要键(通常是右键),`4`(二进制`100`)表示按下辅助键(通常是中间键)。因此,如果返回`3`(二进制`011`)就表示同时按下了左键和右键。 |
| 26 | +- `relatedTarget`:节点对象,表示事件的相关节点,默认为`null`。`mouseenter`和`mouseover`事件时,表示鼠标刚刚离开的那个元素节点;`mouseout`和`mouseleave`事件时,表示鼠标正在进入的那个元素节点。 |
| 27 | + |
| 28 | +下面是一个例子。 |
| 29 | + |
| 30 | +```javascript |
| 31 | +function simulateClick() { |
| 32 | + var event = new MouseEvent('click', { |
| 33 | + 'bubbles': true, |
| 34 | + 'cancelable': true |
| 35 | + }); |
| 36 | + var cb = document.getElementById('checkbox'); |
| 37 | + cb.dispatchEvent(event); |
| 38 | +} |
| 39 | +``` |
| 40 | + |
| 41 | +上面代码生成一个鼠标点击事件,并触发该事件。 |
| 42 | + |
| 43 | +## MouseEvent 接口的实例属性 |
| 44 | + |
| 45 | +### MouseEvent.altKey,MouseEvent.ctrlKey,MouseEvent.metaKey,MouseEvent.shiftKey |
| 46 | + |
| 47 | +`MouseEvent.altKey`、`MouseEvent.ctrlKey`、`MouseEvent.metaKey`、`MouseEvent.shiftKey`这四个属性都返回一个布尔值,表示事件发生时,是否按下对应的键。它们都是只读属性。 |
| 48 | + |
| 49 | +- `altKey`属性:Alt 键 |
| 50 | +- `ctrlKey`属性:Ctrl 键 |
| 51 | +- `metaKey`属性:Meta 键(Mac 键盘是一个四瓣的小花,Windows 键盘是 Windows 键) |
| 52 | +- `shiftKey`属性:Shift 键 |
| 53 | + |
| 54 | +```javascript |
| 55 | +// HTML 代码如下 |
| 56 | +// <body onclick="showKey(event)"> |
| 57 | +function showKey(e) { |
| 58 | + console.log('ALT key pressed: ' + e.altKey); |
| 59 | + console.log('CTRL key pressed: ' + e.ctrlKey); |
| 60 | + console.log('META key pressed: ' + e.metaKey); |
| 61 | + console.log('SHIFT key pressed: ' + e.shiftKey); |
| 62 | +} |
| 63 | +``` |
| 64 | + |
| 65 | +上面代码中,点击网页会输出是否同时按下对应的键。 |
| 66 | + |
| 67 | +### MouseEvent.button,MouseEvent.buttons |
| 68 | + |
| 69 | +`MouseEvent.button`属性返回一个数值,表示事件发生时按下了鼠标的哪个键。该属性只读。 |
| 70 | + |
| 71 | +- 0:按下主键(通常是左键),或者该事件没有初始化这个属性(比如`mousemove`事件)。 |
| 72 | +- 1:按下辅助键(通常是中键或者滚轮键)。 |
| 73 | +- 2:按下次键(通常是右键)。 |
| 74 | + |
| 75 | +```javascript |
| 76 | +// HTML 代码为 |
| 77 | +// <button onmouseup="whichButton(event)">点击</button> |
| 78 | +var whichButton = function (e) { |
| 79 | + switch (e.button) { |
| 80 | + case 0: |
| 81 | + console.log('Left button clicked.'); |
| 82 | + break; |
| 83 | + case 1: |
| 84 | + console.log('Middle button clicked.'); |
| 85 | + break; |
| 86 | + case 2: |
| 87 | + console.log('Right button clicked.'); |
| 88 | + break; |
| 89 | + default: |
| 90 | + console.log('Unexpected code: ' + e.button); |
| 91 | + } |
| 92 | +} |
| 93 | +``` |
| 94 | + |
| 95 | +`MouseEvent.buttons`属性返回一个三个比特位的值,表示同时按下了哪些键。它用来处理同时按下多个鼠标键的情况。该属性只读。 |
| 96 | + |
| 97 | +- 1:二进制为`001`(十进制的1),表示按下左键。 |
| 98 | +- 2:二进制为`010`(十进制的2),表示按下右键。 |
| 99 | +- 4:二进制为`100`(十进制的4),表示按下中键或滚轮键。 |
| 100 | + |
| 101 | +同时按下多个键的时候,每个按下的键对应的比特位都会有值。比如,同时按下左键和右键,会返回3(二进制为011)。 |
| 102 | + |
| 103 | +### MouseEvent.clientX,MouseEvent.clientY |
| 104 | + |
| 105 | +`MouseEvent.clientX`属性返回鼠标位置相对于浏览器窗口左上角的水平坐标(单位像素),`MouseEvent.clientY`属性返回垂直坐标。这两个属性都是只读属性。 |
| 106 | + |
| 107 | +```javascript |
| 108 | +// HTML 代码为 |
| 109 | +// <body onmousedown="showCoords(event)"> |
| 110 | +function showCoords(evt){ |
| 111 | + console.log( |
| 112 | + 'clientX value: ' + evt.clientX + '\n' + |
| 113 | + 'clientY value: ' + evt.clientY + '\n' |
| 114 | + ); |
| 115 | +} |
| 116 | +``` |
| 117 | + |
| 118 | +这两个属性还分别有一个别名`MouseEvent.x`和`MouseEvent.y`。 |
| 119 | + |
| 120 | +### MouseEvent.movementX,MouseEvent.movementY |
| 121 | + |
| 122 | +`MouseEvent.movementX`属性返回当前位置与上一个`mousemove`事件之间的水平距离(单位像素)。数值上,它等于下面的计算公式。 |
| 123 | + |
| 124 | +```javascript |
| 125 | +currentEvent.movementX = currentEvent.screenX - previousEvent.screenX |
| 126 | +``` |
| 127 | + |
| 128 | +`MouseEvent.movementY`属性返回当前位置与上一个`mousemove`事件之间的垂直距离(单位像素)。数值上,它等于下面的计算公式。 |
| 129 | + |
| 130 | +```javascript |
| 131 | +currentEvent.movementY = currentEvent.screenY - previousEvent.screenY。 |
| 132 | +``` |
| 133 | + |
| 134 | +这两个属性都是只读属性。 |
| 135 | + |
| 136 | +### MouseEvent.screenX,MouseEvent.screenY |
| 137 | + |
| 138 | +`MouseEvent.screenX`属性返回鼠标位置相对于屏幕左上角的水平坐标(单位像素),`MouseEvent.screenY`属性返回垂直坐标。这两个属性都是只读属性。 |
| 139 | + |
| 140 | +```javascript |
| 141 | +// HTML 代码如下 |
| 142 | +// <body onmousedown="showCoords(event)"> |
| 143 | +function showCoords(evt) { |
| 144 | + console.log( |
| 145 | + 'screenX value: ' + evt.screenX + '\n' |
| 146 | + 'screenY value: ' + evt.screenY + '\n' |
| 147 | + ); |
| 148 | +} |
| 149 | +``` |
| 150 | + |
| 151 | +### MouseEvent.offsetX,MouseEvent.offsetY |
| 152 | + |
| 153 | +`MouseEvent.offsetX`属性返回鼠标位置与目标节点左侧的`padding`边缘的水平距离(单位像素),`MouseEvent.offsetY`属性返回与目标节点上方的`padding`边缘的垂直距离。这两个属性都是只读属性。 |
| 154 | + |
| 155 | +```javascript |
| 156 | +/* HTML 代码如下 |
| 157 | + <style> |
| 158 | + p { |
| 159 | + width: 100px; |
| 160 | + height: 100px; |
| 161 | + padding: 100px; |
| 162 | + } |
| 163 | + </style> |
| 164 | + <p>Hello</p> |
| 165 | +*/ |
| 166 | +var p = document.querySelector('p'); |
| 167 | +p.addEventListener( |
| 168 | + 'click', |
| 169 | + function (e) { |
| 170 | + console.log(e.offsetX); |
| 171 | + console.log(e.offsetY); |
| 172 | + }, |
| 173 | + false |
| 174 | +); |
| 175 | +``` |
| 176 | + |
| 177 | +上面代码中,鼠标如果在`p`元素的中心位置点击,会返回`150 150`。因此中心位置距离左侧和上方的`padding`边缘,等于`padding`的宽度(100像素)加上元素内容区域一半的宽度(50像素)。 |
| 178 | + |
| 179 | +### MouseEvent.pageX,MouseEvent.pageY |
| 180 | + |
| 181 | +`MouseEvent.pageX`属性返回鼠标位置与文档左侧边缘的距离(单位像素),`MouseEvent.pageY`属性返回与文档上侧边缘的距离(单位像素)。它们的返回值都包括文档不可见的部分。这两个属性都是只读。 |
| 182 | + |
| 183 | +```javascript |
| 184 | +/* HTML 代码如下 |
| 185 | + <style> |
| 186 | + body { |
| 187 | + height: 2000px; |
| 188 | + } |
| 189 | + </style> |
| 190 | +*/ |
| 191 | +document.body.addEventListener( |
| 192 | + 'click', |
| 193 | + function (e) { |
| 194 | + console.log(e.pageX); |
| 195 | + console.log(e.pageY); |
| 196 | + }, |
| 197 | + false |
| 198 | +); |
| 199 | +``` |
| 200 | + |
| 201 | +上面代码中,页面高度为2000像素,会产生垂直滚动条。滚动到页面底部,点击鼠标输出的`pageY`值会接近2000。 |
| 202 | + |
| 203 | +### MouseEvent.relatedTarget |
| 204 | + |
| 205 | +`MouseEvent.relatedTarget`属性返回事件的相关节点。对于那些没有相关节点的事件,该属性返回`null`。该属性只读。 |
| 206 | + |
| 207 | +下表列出不同事件的`target`属性值和`relatedTarget`属性值义。 |
| 208 | + |
| 209 | +|事件名称 |target 属性 |relatedTarget 属性 | |
| 210 | +|---------|-----------|------------------| |
| 211 | +|focusin |接受焦点的节点 |丧失焦点的节点 | |
| 212 | +|focusout |丧失焦点的节点 |接受焦点的节点 | |
| 213 | +|mouseenter |将要进入的节点 |将要离开的节点 | |
| 214 | +|mouseleave |将要离开的节点 |将要进入的节点 | |
| 215 | +|mouseout |将要离开的节点 |将要进入的节点 | |
| 216 | +|mouseover |将要进入的节点 |将要离开的节点 | |
| 217 | +|dragenter |将要进入的节点 |将要离开的节点 | |
| 218 | +|dragexit |将要离开的节点 |将要进入的节点 | |
| 219 | + |
| 220 | +下面是一个例子。 |
| 221 | + |
| 222 | +```javascript |
| 223 | +/* |
| 224 | + HTML 代码如下 |
| 225 | + <div id="outer" style="height:50px;width:50px;border-width:1px solid black;"> |
| 226 | + <div id="inner" style="height:25px;width:25px;border:1px solid black;"></div> |
| 227 | + </div> |
| 228 | +*/ |
| 229 | + |
| 230 | +var inner = document.getElementById('inner'); |
| 231 | +inner.addEventListener('mouseover', function (event) { |
| 232 | + console.log('进入' + event.target.id + ' 离开' + event.relatedTarget.id); |
| 233 | +}, false); |
| 234 | +inner.addEventListener('mouseenter', function (event) { |
| 235 | + console.log('进入' + event.target.id + ' 离开' + event.relatedTarget.id); |
| 236 | +}); |
| 237 | +inner.addEventListener('mouseout', function () { |
| 238 | + console.log('离开' + event.target.id + ' 进入' + event.relatedTarget.id); |
| 239 | +}); |
| 240 | +inner.addEventListener("mouseleave", function (){ |
| 241 | + console.log('离开' + event.target.id + ' 进入' + event.relatedTarget.id); |
| 242 | +}); |
| 243 | + |
| 244 | +// 鼠标从 outer 进入inner,输出 |
| 245 | +// 进入inner 离开outer |
| 246 | +// 进入inner 离开outer |
| 247 | + |
| 248 | +// 鼠标从 inner进入 outer,输出 |
| 249 | +// 离开inner 进入outer |
| 250 | +// 离开inner 进入outer |
| 251 | +``` |
| 252 | + |
| 253 | +## MouseEvent 接口的实例方法 |
| 254 | + |
| 255 | +### MouseEvent.getModifierState() |
| 256 | + |
| 257 | +`MouseEvent.getModifierState`方法返回一个布尔值,表示有没有按下特定的功能键。它的参数是一个表示[功能键](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/getModifierState#Modifier_keys_on_Gecko)的字符串。 |
| 258 | + |
| 259 | +```javascript |
| 260 | +document.addEventListener('click', function (e) { |
| 261 | + console.log(e.getModifierState('CapsLock')); |
| 262 | +}, false); |
| 263 | +``` |
| 264 | + |
| 265 | +上面的代码可以了解用户是否按下了大写键。 |
| 266 | + |
0 commit comments