JavaScript 事件-事件流,事件冒泡,事件捕获,事件绑定与解绑,事件委托、阻止冒泡、阻止默认行为详细篇

今天药忘吃喽~ 2021-11-16 06:14 576阅读 0赞

一、事件流

事件流描述的是从页面中接受事件的顺序,当几个都具有事件的元素层叠在一起的时候,那么你点击其中一个元素,并不是只有当前被点击的元素会触发事件,而层叠在你点击范围的所有元素都会触发事件。

事件流包括两种模式:冒泡和捕获

当一个DOM事件被触发时,它不仅仅只是单纯地在本身对象上触发一次,而是会经历三个不同的阶段:

捕获阶段:先由文档的根节点document往事件触发对象,从外向内捕获事件对象;
目标阶段:到达目标事件位置(事发地),触发事件;
冒泡阶段:再从目标事件位置往文档的根节点方向回溯,从内向外冒泡事件对象。

事件冒泡:

子集元素先触发,父级元素后触;(由内到外)

子集元素和父元素具备同样的事件,当触发子元素时,也会触发父元素的事件。
在这里插入图片描述

事件捕获:

父级元素先触发,子集元素后触发;(由外到内)

在这里插入图片描述

二、事件绑定与解绑

(1)element.addEventListener(event, function, useCapture);
element.removeEventListener(event, function, useCapture);IE8及以下不支持

IE不支持addEventListener和removeEventListener方法

第一个参数:必须。字符串,指定事件名。不要使用 “on” 前缀。 例如,使用 “click” ,而不是使用 “onclick”。

第二个参数:必须。指定要事件触发时执行的函数。

第三个参数:可选。布尔值,指定事件是否在捕获或冒泡阶段执行。
true - 事件句柄在捕获阶段执行
false- false- 默认。事件句柄在冒泡阶段执行

  1. var element=document.getElementById("box");
  2. var handler=function(){
  3. event.preventDefault( ); //阻止默认事件
  4. }
  5. //绑定事件
  6. element.addEventListener('click', handler, false);
  7. //解绑事件
  8. element.removeEventListener('click', handle, false);
(2)attachEvent(event.type, handle );
detachEvent(“onclick”, handler); IE特有,兼容IE8及以下,可添加多个事件处理程序,只支持冒泡阶段,并不属于DOM2

有类似于addEventListener的方法:attachEvent();detachEvent(); 区别就是attachEvent()的参数只有两个且和addEventListener()前两个参数一致,只支持冒泡

  1. var element=document.getElementById("box");
  2. var handler=function(){
  3. event.returnValue = false; //阻止默认事件
  4. }
  5. //绑定事件
  6. element.attachEvent('onclick', handler);
  7. //解绑事件,参数和绑定一样
  8. element.detachEvent("onclick", handler);
(3)封装事件绑定与解绑函数,兼容浏览器
  1. //用事件冒泡方式,如果想兼容事件捕获只需要添加个bool参数
  2. var EventUtil = {
  3. addEvent: function(element,type,handler) {
  4. if (element.addEventListener) {
  5. element.addEventListener(type,handler,false);
  6. }
  7. else if (element.attachEvent) {
  8. element.attachEvent('on'+type,handler);
  9. }
  10. else {
  11. element['on'+type] = handler;
  12. }
  13. },
  14. removeEvent: function(element,type,handler) {
  15. if (element.removeEventListener)
  16. {
  17. element.removeEventListener(type,handler,false);
  18. }
  19. else if(element.detachEvent) {
  20. element.detachEvent('on' +type,handler);
  21. }
  22. else {
  23. element['on'+type] = null;
  24. }
  25. }
  26. }

//如何调用

  1. var box= document.getElementById("box");
  2. var handler = function(){
  3. console.log(111);
  4. };
  5. EventUtil.addEvent(box, "click", handler);
  6. EventUtil.removeEvent(box, "click", handler);

三、阻止冒泡

event.stopPropagation() 阻止事件冒泡的产生
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1">
  6. <title></title>
  7. <style>
  8. #demo1 {
  9. width: 300px;
  10. height: 300px;
  11. background: red;
  12. }
  13. #demo2 {
  14. width: 200px;
  15. height: 200px;
  16. background: blue;
  17. }
  18. #demo3 {
  19. width: 100px;
  20. height: 100px;
  21. background: yellow;
  22. }
  23. </style>
  24. <script type="text/javascript">
  25. window.onload = function() {
  26. var demo1 = document.getElementById("demo1");
  27. var demo2 = document.getElementById("demo2");
  28. var demo3 = document.getElementById("demo3");
  29. var fnDome = function() {
  30. alert(this.id)
  31. }
  32. function fnStop() {
  33. alert(this.id);
  34. event.stopPropagation();
  35. //event.stopPropagation() 阻止事件冒泡的产生
  36. //Propagation(繁殖、传播 )
  37. }
  38. //单独一项一项测试时
  39. //demo1.addEventListener("click", fnDome, false); //demo1,点击三个div都会弹出
  40. //demo2.addEventListener("click", fnDome, false); //demo2,点击demo2,demo3两个div都会弹出
  41. //demo3.addEventListener("click", fnDome, false); //demo3,点击demo3这个div
  42. //demo1.addEventListener("click", fnDome, true); //demo1点击三个div都会弹出
  43. //demo2.addEventListener("click", fnDome, true); //demo1,点击demo2,demo3两个div都会弹出
  44. // demo3.addEventListener("click", fnDome, true); //demo1,点击demo3这个div
  45. //demo1.addEventListener("click", fnStop, false); //demo1,点击三个div都会弹出
  46. //demo2.addEventListener("click", fnStop, false); //demo2,点击demo2,demo3两个div都会弹出
  47. //demo3.addEventListener("click", fnStop, false); //demo3,点击demo3这个div
  48. //demo1.addEventListener("click", fnStop, true); //demo1,点击三个div都会弹出
  49. //demo2.addEventListener("click", fnStop, true); //demo2,点击demo2,demo3两个div都会弹出
  50. //demo3.addEventListener("click", fnStop, true); //demo3,点击demo3这个div
  51. //事件处理函数不能加括号,否则会直接执行
  52. //总结:当选中一个节点时,无论是冒泡还是捕获,里面的节点有同样的事件
  53. //第二次测试,合并测试,当一个事假有多个节点时
  54. // demo1.addEventListener("click", fnDome, false); //一次,demo1
  55. // demo2.addEventListener("click", fnDome, false); //二次,demo2,demo1
  56. // demo3.addEventListener("click", fnDome, false); //三次,demo3,demo2,demo1
  57. //总结:冒泡事件按从内到外依次执行
  58. //第三次测试,合并测试,当一个事假有多个节点时
  59. // demo1.addEventListener("click", fnDome, true); //demo1
  60. // demo2.addEventListener("click", fnDome, true); //demo1,demo2
  61. // demo3.addEventListener("click", fnDome, true); //demo1,demo2,demo3
  62. //总结:鋪貨事件按从外到内依次执行
  63. //第四次测试,合并测试,当一个事假有多个节点时
  64. // demo1.addEventListener("click", fnStop, false); //demo1
  65. // demo2.addEventListener("click", fnStop, false); //demo2
  66. // demo3.addEventListener("click", fnStop, false); //demo3
  67. //第五次测试,合并测试,当一个事假有多个节点时
  68. //demo1.addEventListener("click", fnStop, true); //demo1
  69. demo2.addEventListener("click", fnStop, true); //demo1
  70. demo3.addEventListener("click", fnStop, true); //demo1
  71. }
  72. </script>
  73. </head>
  74. <body>
  75. <div id="demo1">1
  76. <div id="demo2">2
  77. <div id="demo3">3
  78. </div>
  79. </div>
  80. </div>
  81. </body>
  82. </html>

总结:
(1)当选中一个节点时,无论是冒泡还是捕获,节点里面的节点有同样的事件

(2)当一个事件有多个节点时,冒泡事件按从内到外依次执行

(3)当一个事件有多个节点时,捕获事件按从外到内依次执行

(4)当一个事件有多个节点时,阻止事件冒泡的产生,冒泡事件,只会执行当前或包含的节点事件,不会冒泡,执行完里面节点的事件不会接着执行包含节点的节点事件,也就是说只会执行一次,如果不阻止事件冒泡的产生,则会将事件一个个执行完

(5)当一个事件有多个节点时,阻止事件冒泡的产生,捕获事件,只会执行第一个捕获到的事件

四、阻止默认

w3c 的方法是 e.preventDefault(),
IE 则是使用 e.returnValue =false;

preventDefault 它是事件对象(Event)的一个方法,作用是取消一个目标元素的默认行为。比如超链接a

  1. <body>
  2. <a href="事件冒泡.html" target="_blank">啦啦啦啦啦</a>
  3. <script type="text/javascript">
  4. var a1=document.getElementsByTagName('a')[0];
  5. //传统用法阻止事件的默认发生
  6. // a1.οnclick=function(e){
  7. // e.preventDefault();
  8. // }
  9. //使用DOM方法来阻止默认发生
  10. a1.addEventListener('click',show);
  11. //兼容
  12. function show(e){
  13. if (e.preventDefault) {
  14. e.preventDefault();
  15. } else{
  16. window.event.returnValue=false;
  17. }
  18. }
  19. </script>
  20. </body>

发表评论

表情:
评论列表 (有 0 条评论,576人围观)

还没有评论,来说两句吧...

相关阅读