Skip to content

Latest commit

 

History

History
100 lines (78 loc) · 4.18 KB

README.md

File metadata and controls

100 lines (78 loc) · 4.18 KB

Event Order

问题:

有dom节点如下:

<div id="parent">
    <div id="son">
        this is the son 
    </div>
</div>

<script>
    var parent = document.getElementById('parent');
    var son = document.getElementById('son');
    parent.addEventListener('click',function(){
        console.log('parent');
    })
    son.addEventListener('click',function(){
        console.log('son');
    });
</script>
-----------------------------------
| element1                        |
|   -------------------------     |
|   |element2               |     |
|   -------------------------     |
|                                 |
-----------------------------------

如果你是最初Event Object Model的设计者,那么你会设计成谁应该先执行click事件?(思考10s)

历史上那个不和谐的年代

NetScape 说:parent上的事件先执行。为什么呢?因为这叫event capturing (事件捕获)。从技术上来讲的确是这样子的,一个 click 发生时,鼠标会触发一个系统中断并且告诉中断控制器,中断控制器会经过优先级排序后,最终决定是否将这个中断发给CPU,CPU在接收到中断后会去鼠标所对应的IO端口取得一系列的值,这些值是一些关于此次点击事件的参数,比如哪个键啊,点击的位置啊之类的,然后将这个click事件派送给处于active的进程,最终click事件首先被浏览器捕获,然后根据dom树向目标节点传递。最终会触发目标节点的事件监听函数。

               | |
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  \ /          |     |
|   -------------------------     |
|        Event CAPTURING          |
-----------------------------------

MicroSoft 说:son上的事件先执行。为什么呢?因为这叫event bubbling(事件冒泡)。NetScape你说的是有道理,但是我不听啊。你打我啊。技术实现是你说的这样子没错,但是我们就想一个很简单的问题:难道不应该是点击谁就触发谁酱紫才更符合我们人类的使用习惯吗?

               / \
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  | |          |     |
|   -------------------------     |
|        Event BUBBLING           |
-----------------------------------

想想这样子的日子多蛋疼,web developer给一些列的节点绑定了事件监听,但是特么的在NetScape浏览器上和IE浏览器上一堆函数的执行顺序不一样。

让我来吧

w3c来了。他说:“你们不要吵了,大家都坐下来喝喝茶聊聊,这样子闹下去没有好的结果啊,对你们自己家的浏览器发展也没什么好处啊,这样吧,都听我的,我来想个办法吧。”

然后w3c的事件对象模型就出来了,方案是:我先按照NetScape捕获的顺序到达目标节点,然后再按照MicroSoft冒泡的顺序返回到window。这样总可以了吧,两个人都没有违背嘛。但是有个问题啊,这样子绑定在同一个节点上的事件岂不是要背执行两次?w3c说了:“是啊,按照正常是会被执行两次啊,但是我们可以让jser在写事件监听的时候自己选择啊,传个参数不就得了嘛”。有人问,如果忘了呢?“那就给他个默认的参数嘛”;于是乎:

                 | |  / \
-----------------| |--| |-----------------
| element1       | |  | |                |
|   -------------| |--| |-----------     |
|   |element2    \ /  | |          |     |
|   --------------------------------     |
|        W3C event model                 |
------------------------------------------
element.addEventListener(event.type,callback[,boolen])
//第三个可选的参数是一个布尔值。
//如果是true,则此事件会在capturing的过程中被执行;
//如果是false则此事件会在bubbling的过程中被执行;
//默认不传是false.

尘埃落定

浏览器事件触发顺序终于在w3c的斡旋下统一了,天下jser高歌欢庆。

参考文档:

http://www.quirksmode.org/js/events_order.html