js 事件

292 阅读3分钟

1.事件基础

   什么是 事件
    * 事件是一种通知机制
    * 事件是按照事件类型进行匹配

    * clickHandler只能是一个回调函数,不能直接执行
    * 因为当收到事件时,执行该函数,如果加()表示立即执行,收到事件后就不会执行了
    * addEventListener这个方法并没有对于clickHandler函数的返回结果做处理,因此clickHandler使用return无效
    * 这里clickHandler是不能传参的,clickHandler里面有且只有一个参数是event对象
    
    事件侦听对象.addEventListener("click",clickHandler);
    function clickHandler(e){
        // return 事件函数中不要使用return
    }
   什么是 事件侦听对象
        EventTarget所有继承这个类的类别都可以作为事件侦听对象,DOM
        谁侦听,谁抛发
        侦听对象和抛发对象必须相同
        侦听事件类型和抛发事件类型必须相同


        var div=document.querySelector("div");
        div.addEventListener("nihao",nihaoHandler);

        var evt=new Event("nihao");
        evt.num=10;
        div.dispatchEvent(evt);

        function nihaoHandler(e){
            // e.type 事件类型nihao
            console.log(e===evt);
        }
解耦
中介者

事件侦听对象(事件抛发对象)  基于EventTarget创建对象,DOM对象也是事件侦听对象
主要用于侦听事件和抛发事件


事件对象 基于Event创建对象 new Event(事件类型type) 事件对象就是被传递的对象,
被抛发出去或者在事件回调函数中收到的参数e

事件回调函数 写在事件侦听addEventListener中,这个函数不能写return,不能传参
有且只有一个参数,这个参数就是事件对象

事件对象类型,每个事件都有对应类型,这个类型可以是系统类型,也可以是自定义类型,
但是都必须是字符串,在事件对象中可以通过type获取该类型e.type

事件分为系统事件和自定义事件,不管是系统事件还是自定义事件,我们都可以利用
dispatchEvent()来触发该事件侦听函数,系统事件一般在实际触发时由系统自动抛发事件
不需要我们手动抛发,当然我们可以随时触发它
        var et=new EventTarget();

        var obj1={
            a:1,
            init:function(){
               et.addEventListener("aa",this.calls);
               et.a=this.a;
            },
            calls:function(e){
               console.log(e.c);
               var evt=new Event("bb");
               evt.a=this.a;
               et.dispatchEvent(evt);
            }
        }

        var obj2={
            b:2,
            init:function(){
            et.addEventListener("bb",this.calls);
            var evt=new Event("aa");
            evt.b=this.b;
            evt.c=3;
            et.dispatchEvent(evt);
            },
            calls:function(e){
               console.log(e);
            }
        }


        obj1.init();
        obj2.init();

2.事件原理

* 事件原理分为3个阶段:捕获阶段(由外至内)   目标阶段(目标阶段)    冒泡阶段(由内至外)
* 实际侦听触发的顺序是冒泡阶段触发的

  var div0 = document.querySelector(".div0");
  var div1 = document.querySelector(".div1");
  var div2 = document.querySelector(".div2");
   * 如果想在捕获阶段触发侦听
  第一个参数是事件类型  type
  第二个参数是事件回调函数
  第三个参数是是否捕获阶段触发  默认是false(冒泡阶段) true是捕获阶段
  div0.addEventListener("click", clickHandler0);
  div1.addEventListener("click", clickHandler1,true);
  div2.addEventListener("click", clickHandler2);

  // e.srcElement IE兼容写法
  function clickHandler0(e) {
      // this就是执行该函数的事件侦听对象,e.currentTarget也是事件侦听对象,谁添加的侦听
      // e.target和e.srcElement 就是事件目标对象,实际点的是谁
      console.log("div0:",this,e.currentTarget,e.target,e.srcElement);

      // var arr=[];
      // arr.forEach(function(item){
      //     console.log(e.currentTarget);
      // })
  }

  function clickHandler1(e) {
      console.log("div1:",this,e.currentTarget,e.target,e.srcElement);
      e.stopPropagation();//停止冒泡,阻止冒泡
  }

  function clickHandler2(e) {
      console.log("div2:",this,e.currentTarget,e.target,e.srcElement);
  }
  
  
  * 事件委托
        var ul=document.querySelector("ul");
        ul.addEventListener("click",clickHandler);

        function clickHandler(e){
            // console.log(this);
            // if(e.target.nodeName!=="LI") return;
            if(e.target.constructor!==HTMLLIElement) return;
            var index=Array.from(ul.children).indexOf(e.target);
            console.log(index);

            // this.removeEventListener("click",clickHandler);//销毁事件
        }