1.事件流
假设有这样一个场景:
有一个导航条:div > ul > li > a,每个元素块宽高一样,就像是一组同心圆。如果我们点击a元素,那么浏览器会认为单击事件不仅仅发生在a上。换句话说,在我们单击a元素的同事,我们也单击了容器中的其他元素。
事件流描述的是从页面中接收事件的顺序。但有意思的是,IE 和 Netscape 却分别提出了不一样的事件流概念。IE 的事件流是事件冒泡,而Netscape的事件流是事件捕获流。
那么问题来了,什么是事件冒泡?什么是事件捕获?
2.事件冒泡
事件冒泡:就是说事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点。
<!DOCTYPE html> <html> <head> <title>example</title> </head> <body> <div>click</div> </body> <html>
以上代码,如果我们点击页面中的<div>,那么这个click事件会按照以下顺序传播:
<div> => <body> => <html> => document
3.事件捕获
事件捕获:与事件冒泡差不多完全相反,事件捕获思想是从不太具体的节点应该更早接收到事件,而具体的节点应该是最后接收到事件。
那么如果我们点击页面中的<div>,那么这个click事件会按照以下顺序传播:
document => <html> => <body> => <div>
虽然事件捕获是Netscap唯一支持的事件流模型,但是IE9/safari/chrome/opera/firefox目前都支持这种事件流模型。尽管“DOM2级事件”规范要求事件应该从document对象开始传播,但是这些浏览器都是从window对象开始捕获事件的。
那么问题又来了,什么是“DOM2级事件”?
4.DOM事件流
“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段--处于目标阶段--事件冒泡阶段。
还是用上面的代码为例:
document => <html> => <body> => <div> => <body> => <html> => document
捕获阶段 处于目标阶段 冒泡阶段
在DOM事件流中,实际目标在捕获阶段是不会接收到事件的。这意味着捕获阶段到<body>就停止了。下一个阶段是“处于目标阶段”,即事件在<div>上发生,而这一个阶段被堪称冒泡阶段的一部分。继而冒泡阶段发生,事件传回document。