关于JavaScript事件流是指浏览器中页面接收到事件的顺序.
事件流原理如下图所示:
由图中可以看出一个完整的JS事件是由window开始,再回到window.
事件流包括捕获过程(1-5),目标过程(5-6),冒泡过程(6-10),首先讲一下冒泡过程.
关于事件冒泡其实就是一个自内向外的过程.我们可以写下以下代码:
当点击btn时会先弹出btn后弹出content.
为什么不是只弹出btn呢?因为JS事件是从window开始再回到window.也就是说在以上过程中,当点击btn时是先从 window->document->body->div,事件捕获,找到btn,然后再进行冒泡,先弹出btn,再到content弹出content.
由此也可见事件捕获是一个自外向内的过程.
现在的浏览器都支持事件捕获和事件冒泡,因为比较低版本的浏览器(IE6,IE7,IE8)只支持冒泡流,所以建议使用冒泡流,除非有时候需要用到事件捕抓获
然而有时候JS事件流不会遵循上图的顺序,如
DOM Level0并不支持捕获事件.
运行以上代码时,会先弹出btn2再弹出content. btn2事件会覆盖btn1事件,这是因为在DOM Level0下,一个元素只能绑定一个事件.而且DOM Level0不能阻止事件冒泡.
当DOM level2时运行以下代码
浏览器会先弹出btn1,接着弹出btn2,再弹出content.这是因为在DOM Level2下,一个元素可以绑定多个事件.
现在谈一下addEventListener的第三个参数,当这个参数为true时表示允许在事件捕获时调用函数,当参数为false时表示允许在事件冒泡时调用函数.
运行一下代码:
浏览器会先弹出content,接着弹出btn1,再弹出btn2,因为content注册事件时允许在捕获过程调用函数.
而在IE浏览器下注册事件只能用attachEvent函数,attachEvent只有两个参数,第一个是注册的事件类型(得加上"on"),第二个是执行的函数.
为了兼容浏览器,可运用一下代码:
而关于事件的preventDefault函数,这个函数可用于阻止事件默认行为,比如可以用于阻止链接触发跳转到新窗口.
关于事件的stopPropagation函数,可用于阻止事件冒泡,如一下代码:
当出发btn时,浏览器会弹出btn1而没有弹出content,因为触发btn时阻止了事件冒泡.
接下来讲一下事件委托.
事件委托也称事件代理,是利用事件冒泡,指定一个事件处理程序,就可以管理某一类的所有事件.
例如一个导航栏,需要点击各项时显示各项的信息,如果此时挨个挨个的给予函数,费力不讨好.因为每个函数都是对象,都会占用内存,内存高,性能就低.所以利用事件委托是个不错的选择.
如下图:
当点击每一项时都会显示每一项的信息,简便且节省资源.当触发单项时会进行冒泡到ul,执行showColor函数,输出事件目标的信息.