事件捕获与事件冒泡:
- 事件捕获:由微软公司提出,事件从文档根节点(Document 对象)流向目标节点,途中会经过目标节点的各个父级节点,并在这些节点上触发捕获事件,直至到达事件的目标节点;
- 事件冒泡:由网景公司提出,与事件捕获相反,事件会从目标节点流向文档根节点,途中会经过目标节点的各个父级节点,并在这些节点上触发捕获事件,直至到达文档的根节点。整个过程就像水中的气泡一样,从水底向上运动
W3C 为了统一标准,采用了一个折中的方式,即将事件捕获与事件冒泡合并,也就是现在的“先捕获后冒泡”
addEventListener的第三个参数
这个一个给事件绑定监听函数的方法,它接收三个参数
element.addEventListener(event, function, useCapture)
第一个参数是需要绑定的事件(字符串,指定事件名,不要用on前缀,使用click而不是使用onclick)
第二个参数指定事件触发时执行的函数
第三个参数默认为false,指定事件流为事件冒泡,设为为true时指定为事件捕获。
冒泡
//事件冒泡 <div id="s1">s1 <div id="s2">s2</div> </div> <script> s1.addEventListener("click",function(){ console.log("s1冒泡事件") }); s2.addEventListener("click",function(){ console.log("s2冒泡事件") }) </script> //结果 点击s1输出结果:s1冒泡事件 点击s2输出结果:s2冒泡事件,s1冒泡事件
- 当点击s1时,先触发s1的点击事件,然后向上触发直至document,上面没有其他的点击事件了,所以只输出“s1冒泡事件”这个结果。
- 当点击s2时,先触发s2的点击事件,所以先打印出“s2冒泡事件”,然后向上触发至s1,又打印出“s1冒泡事件”,再向上触发直至document。
捕获
//事件捕获 <div id="s1">s1 <div id="s2">s2</div> </div> <script> s1.addEventListener("click",function(){ console.log("s1捕获事件") },true); s2.addEventListener("click",function(){ console.log("s2捕获事件") },true) </script> //结果 点击s1输出结果:s1捕获事件 点击s2输出结果:s1捕获事件,s2捕获事件
- 当点击s1时,先触发最外层document,然后向下触发直至具体元素s1,只有s1上监听了click事件,所以只输出“s1捕获事件”这个结果。
- 当点击s2时,先触发最外层document,然后向下触发s1的click事件,所以打印“s1捕获事件”这个结果,然后继续向下触发到s2,又打印出“s2捕获事件”。
5.事件委托
- 事件委托是利用事件冒泡的原理。
- 使用情况:当有多个类似的元素需要绑定事件时,一个一个去绑定既浪费时间,又不利于性能,这时候可以使用事件委托,给他们的一个共同父级元素添加一个事件函数去处理所有的事件情况。
<ul id="father"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> <script> father.addEventListener("click",function(e){ if(e.target!=father){ console.log(e.target.innerText) } }); </script> //结果 点击哪个li,就输出那个的文字
因为采用的事件冒泡的事件流,所以当点击li元素时,向上触发他们的父元素上的点击事件。
优点:
1、性能 不需要循环所有的元素一个个绑定事件
2、灵活 当有新的子元素时不需要重新绑定事件
取消冒泡事件:
w3c标准 event.stopPropagation(),但ie9以下版本不支持
scroll,mouseleave ,mouseenterfocus,blur,focus,change,submit,reset,select等事件不冒泡。
hover事件不能使用事件委托方式。(鼠标移动到元素上
人生很漫长,或许我只是你人生中微不足道的一小段,只是你人生中的惊鸿一瞥。