让前端飞Web前端之路

JS事件冒泡、事件捕获、事件委托、事件模型

2020-04-28  本文已影响0人  Miaoz0070
JS事件

最近跟同事一起面试,发现同时每次必问JS事件相关的内容,自己就做了下梳理,对其事件相关的内容做了下总结。

事件模型:

顾名思义就是事件的一个流转规则,说到事件模型就跟各个浏览器之间的差异就有关系了,目前浏览器没有统一事件模型,大致分为三种原始事件模型(DOM0级)、DOM2事件模型、IE事件模型。

//主要就是onclick事件
(1)在html代码中直接指定属性值:<button id="demo" type="button" onclick="doSomeTing()" />
(2)在js代码中为 document.getElementsById("demo").onclick = doSomeTing()

优点:所有浏览器都兼容
缺点:
1.逻辑与显示没有分离;
2.相同事件的监听函数只能绑定一个,后绑定的会覆盖掉前面的,如:a.onclick = func1; a.onclick = func2;将只会执行func2中的内容。
3.无法通过事件的冒泡、委托等机制(后面会讲到)完成更多事情。
因为这些缺点,虽然原始事件类型兼容所有浏览器,但仍不推荐使用,当然一般情况我们也很少使用。

其实我们之后要讲的事件冒泡、事件捕获、事件委托都是以此模型来讲解的。


事件冒泡

事件从最具体的元素到不具体的元素,从当前触发的事件目标一级一级往上传递,依次触发,直到document为止。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>xxx</title>
</head>
<body onclick="bodyClick()">
 <div onclick="divClick()">
   <button onclick="btn()">
      <p onclick="p()">点击冒泡</p>
   </button>
  </div>
<script>
       
       function p(){
          console.log('p被点击')
       }
        function btn(){
            console.log("button被点击")
        }
         function divClick(event){
             console.log('div被点击');
         }
        function bodyClick(){
            console.log('body被点击')
        }
//也可以使用
addEventListener('click',function(){ },false);来替换onclick。
</script>
</body>
</html>

p被点击》button被点击》div被点击》body被点击,即具体元素到不具体元素,从p冒泡到根节点。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div>
    <button>
        <p>点击捕获</p>
    </button>
</div>
<script>
    var _p=document.querySelector('p');
    var _b=document.querySelector('button');
    var _d=document.querySelector('div');
    var _body=document.querySelector('body');
   _p.addEventListener('click',function(){
        console.log('p被点击')
    },true);

    _b.addEventListener('click',function(){
        console.log("button被点击")
    },true);

    _d.addEventListener('click',  function(){
        console.log('div被点击')
    },true);

    _body.addEventListener('click',function(){
        console.log('body被点击')
    },true);

</script>
</body>
</html>

事件捕获

从不具体的元素到具体的元素,从document开始触发,一级一级往下传递,依次触发,直到真正事件目标为止。

body被点击》div被点击》buton被点击》p被点击,即跟冒泡是相反的,从不具体元素到具体元素,从根节点到p标签。


事件委托
<ul id="ul">
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
</ul>
ul.addEventListener("click",function(e) { 

   if(e.target && e.target.nodeName.toLowerCase() == "li") {  // 检查事件源e.target是否为li
     console.log("List item ",e.target.id.replace("post-","")," was clicked!");  // 打印当前点击是第几个item 
    } 
});

2.attachEvent() //IE8及IE更早版本,现在已经不怎么使用。
<1>.用法:element.attachEvent(event,function);
(1)event事件加'on',onClick
(2)没有第三个参数,因为IE只有冒泡,没有反向冒泡。
(3)执行顺序按照绑定的反序(先执行后绑定的方法)。
<2>.移除事件监听:element.detachEvent(event,function)

以上就是JS事件冒泡、捕获、委托和事件模型的相关个人理解,有错误之处还请指正。

上一篇 下一篇

猜你喜欢

热点阅读