event fired?

关于事件的产生。就拿鼠标相关事件搞一搞。

消息

当移动鼠标,点击鼠标的时候,OS 是会分发消息的(就说 win32 GUI 吧,或许有其他特例)。至于怎么处理就是应用的事情。(当然 OS 自身作为一个大应用也处理自己该处理的消息。)

事件对象

假如我在浏览器中晃动、点击鼠标,那么 OS 就会把鼠标消息派发给浏览器。此时,关于浏览器中鼠标相关事件(一个事件就是一个JS中的对象,就像这样 {target: xxoo, bubbles: true, type: 'click', cancelable:true, path: ooxx, /* ... */},不同事件对象含有不同信息;一个数据结构而已)的产生我产生了以下的疑问。

  1. click

The click event fires when a pointing device button (e.g., a mouse’s primary button) is pressed and released on a single element. If the button is pressed on one element and released on a different one, the event is fired on the most specific ancestor element that contained both.

click fires after the mousedown and mouseup events, in that order.

我的理解就是:我点了鼠标,浏览器就生成了 click事件,管它有没有谁监听,即使没人理,也要传递一遍。

  1. mouseover

The mouseover event is fired when a pointing device is moved onto the element that has the listener attached or onto one of its children.

移动鼠标,浏览器不一定产生 mouseover事件;只有相关元素监听了 mouseover这类事件,你再去 over,浏览器才会产生 mousemove事件。(这和 click就不一样了;得监听了才有)

  1. mouseenter

The mouseenter event is fired when a pointing device (usually a mouse) is moved over the element that has the listener attached.

Though similar to mouseover, it differs in that it doesn’t bubble and that it isn’t sent to any descendants when the pointer is moved from one of its descendants’ physical space to its own physical space.

下面的图,和图下面的话,我不敢苟同。图中左边和右边情况都不明了,有啥可比性?左边四层div都挂了 mouseenter?还是右边最外层div挂了一个mouseover?

假设左边四层div都挂了 mouseenter,右边最外层div挂了 mouseover。 (默认排版,不加多余样式。)

  • 如果 Text 所处的位置在 他们内部,左边进去到Text上就依次产生了四个 mouseenter事件;右边进去也产生了四个 mouseover事件,每个还冒泡。
  • 如果 Text 所处的位置在 他们外部(比如 fixed 设定位置),那么移动到Text上,左边依次产生了4个事件。右边产生一个事件,冒泡上去。
  1. mousemove

The mousemove event is fired when a pointing device (usually a mouse) is moved while over an element.

这……我在一个元素上晃鼠标,就产生 mousemove事件吗? overenter至少说了需要listener,这个,居然啥也没说?

疑问

就抄这么多了。

  1. 事件的产生

我 click, over, enter, move 时,产生事件有啥条件?

从上面抄的来看,click,就会产生 click事件。这个事件对象的产生没啥要求?即使没有注册一个监听函数?那么这个 click事件 就是打酱油?啥也不干?那要它有何用?当页面单独放一个 checkbox 的时候,点击它,有反应,说明浏览器内部还是有监听的。

  1. 事件的传播

这个三阶段模型也怪怪的。

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
34
35
<!DOCTYPE html>
<html>
<head>
<title>
gg
</title>
</head>
<body>
<div id="test">
<input type="checkbox" id="cb">
</div>
<script>
// C capture, B bubble.
cb.addEventListener('click', e=>{
console.log('cb ', e.eventPhase, e.path);
});

test.addEventListener('click', e=>{
console.log('test C ', e.eventPhase, e.path)
}, true);

test.addEventListener('click', e=>{
console.log('test B ', e.eventPhase, e.path);
});

window.addEventListener('click', e=>{
console.log('w C ', e.eventPhase, e.path);
}, true);

window.addEventListener('click', e=>{
console.log('w B ', e.eventPhase, e.path);
});
</script>
</body>
</html>

任意一个都可以加 e.stopPropagation(),不影响 checkbox 能否选中,影响click事件传播;如果有一个加了 e.preventDefault(),就会影响 checkbox 选中对号,cb.checked === false,也就是不能选中,但不影响click事件传播。

事件非要从window一路下来,一个不拉到达目标?我如果一个事件监听函数都不注册,点击 checkbox,click事件还真的会千辛万苦
window->document->html->body->div#test->input#cb->div#test->body->html->document->window 走一圈?何必呢?一个事件的生命周期有多久?走到头或者stop就消散了吗?

未完待续。