在浏览器运行线程中,有一个线程叫做事件监听线程,这个线程的效果正如字面而言,是用来专门监听事件是否触发的线程,当事件被触发时,事件监听线程就把该事件触发后的执行放到运行栈中去执行,这个时候就会产生一个问题,叫做冒泡触发,要理解冒泡,就得从事件是如何被触发说起。
首先,当我们给document加一个点击事件,在控制台打印“document”字符串;
然后我们再给一个div绑定一个点击事件,在控制台打印“父元素div”字符串;
再在div里面设置一个子元素div,并绑定一个点击事件,在控制台打印“子元素div”字符串;
给div父元素设置宽高200px,给子元素div设置宽高100px;
1、当我们点击父元素div不点击到子元素div时,会按顺序在控制台上打印出“父元素div”“document”;
2、当我们点击子元素div时,会按顺序在控制台上打印出"子元素div"“父元素div”“document”;
为什么会出现这种结果呢?我们就要从程序的思维去理解,当事件监听线程发现有事件触发时,会先从document一级一级向下去寻找触发的那个目标;在这个过程中,因为document是目标的祖父元素,所以也会触发同样的触发事件,父元素div也是同理,这是第一阶段,我们叫做捕获阶段;
第二阶段是目标阶段,这个阶段比较短暂,是在向下捕获的过程中,捕获到了目标元素的时候,这个时候就停止捕获,转变为目标阶段;
第三阶段叫冒泡阶段,从目标元素向父元素一级一级把触发事件加入执行栈中,因为先从目标元素开始,所以先打印“子元素div”后打印父元素“父元素div”最后到“document”,这就是事件触发的全过程。
需要注意的是,判断是否触发事件的阶段是捕获阶段,这个阶段是默认不立刻执行事件的,会在冒泡阶段才执行。
我们可以在绑定事件中给第三个参数,这个参数是个布尔值,用来判断是否在捕获阶段触发,默认为false,可以改为true,那么事件在捕获过程中如果判断触发事事件,会立刻执行,没有设置为true的即在冒泡阶段才执行。