关于js事件流:
document->html->body->div->button 假设有一个结构如此的页面,当用户产生一个行为,比如点击这个button,我们希望浏览器弹出一个提示框,那我们会先获取button这个节点,然后在这个节点的onclick函数内写上弹框,这样我们就可以得到想要的结果,这点很好理解。假设我们给document->html->body->div->button这五个节点分别绑定onclick弹窗,那么用户点击一次button则会弹5次窗,也就是说会触发它所有长辈节点的onclick事件。
用户在与页面交互时,js通过事件来作出不同响应,由于html文档被抽象成DOM结构,而DOM结构是节点包含节点、层层嵌套的父子关系,因此某个节点触发一个事件,就应该触发它所有父辈元素的同类事件,这种方式似乎不太“智能”,可“智能”代表人性化,而人性化是没有标准的,没有标准就无法实现,所以在DOM结构的现状下,这种全部触发的模式是最合理的。
现在就只需要考虑这五个节点的click事件发生的先后顺序了,这个顺序被称为DOM事件流。
按照document->html->body->div->button这个结构。
如果事件触发顺序是:button的click触发--div的click触发--body的click触发--html的click触发--document的click触发,就称之为事件冒泡。
反过来document--html--body--div--button这种触发顺序,就被称之为事件捕获。
两种顺序都有各自的优点:事件捕获可以给我们提供一个拦截事件的机会,因为最外层的节点的事件最先触发,它触发之后才会触发内一级的事件,这个先后顺序就是拦截事件的机会。事件冒泡可以给我们提供一个响应事件的机会,因为最内层的节点的事件最先触发,然后才是上一级的事件,对于已经触发过的事件,我们自然可以在它发生后做出响应。
既然都有优点,那么实际使用的就是两种事件流一起用,document--html--body--div--button--div--body--html--document,先进行事件捕获,再进行事件冒泡,那么介于捕获阶段与冒泡阶段之间的,被称为目标阶段,也就是button节点的click触发阶段 ,但事实上目标阶段与冒泡、捕获阶段没有区分开来,在事件处理程序中:目标阶段的触发可以选择是在捕获还是冒泡阶段,意味着目标阶段可以被触发两次。
node.addEventListener("click", function(){ alert("Hello world!"); }, false); node是被添加事件处理程序的节点,false表示此事件(目标事件)在冒泡阶段触发,true则在捕获阶段触发。