事件基础

事件的原理--自定义事件--抛发事件

        //事件抛发
        //首先给div0 添加一个我们没见过的事件 也就是e.type
        div0.addEventListener("chilema",fn1);
        //实例化事件对象,并且创建一个chilema的事件
        var evt=new Event("chilema");
        //div0 自己抛发这个事件,并执行fn1
        div0.dispatchEvent(evt);

        function fn1(){
            console.log("我吃了");
        }

事件默认是由冒泡触发的,通过Elelement.addEventHandeterLister("click",clickHandler,ture); 第三个参数来修改,默认是flase 捕获不触发

事件触发由三个阶段组成

  1.捕获阶段, 在经过捕获阶段时,是由最外层 document  往内部进行捕获  (事件也可以由捕获触发)

  2.目标阶段  到达目标

  3.冒泡阶段  到达目标后在由内向外冒泡触发事件(默认)

    <script>
        //获取div0 div1 div2 DOM
        var div0=document.querySelector(".div0");
        var div1=document.querySelector(".div1");
        var div2=document.querySelector(".div2");
        //添加事件监听  其中e 是鼠标事件  e.target 是目标对象  e.currentTarget和this一样都是侦听对象
        div0.addEventListener("click",clickHandler0);
        function clickHandler0(e){
            console.log(e.target,e.currentTarget,this);
        }

        div1.addEventListener("click",clickHandler1);
        function clickHandler1(e){
            console.log(e.target,e.currentTarget,this);
        }


        div2.addEventListener("click",clickHandler2);
        function clickHandler2(e){
            console.log(e.target,e.currentTarget,this);
        }
</script>

上述代码,当我们点击最里面的div2的时候,e.currentTarget的 div2、div1、div0  事件是由内向外触发的--也就是冒泡触发

我们来修改代码,把事件监听的第三个参数改成true

    <script>
        //获取div0 div1 div2 DOM
        var div0=document.querySelector(".div0");
        var div1=document.querySelector(".div1");
        var div2=document.querySelector(".div2");
        //添加监听事件,在捕获阶段触发
        div0.addEventListener("click",clickHandler0,true);
        function clickHandler0(e){
            console.log(e.target,e.currentTarget,this);
        }

        div1.addEventListener("click",clickHandler1,true);
        function clickHandler1(e){
            console.log(e.target,e.currentTarget,this);
        }

        div2.addEventListener("click",clickHandler2,true);
        function clickHandler2(e){
            console.log(e.target,e.currentTarget,this);
        }

    </script>

以上代码e.currentTarget就显示的 div0、div1、div2 也就是说在捕获阶段触发的事件

案例1: 当我们点击div2的时候让每个元素,没过1秒后 背景颜色依次变成透明的

 <script>

        var div0=document.querySelector(".div0");
        var div1=document.querySelector(".div1");
        var div2=document.querySelector(".div2");
        var num=1;
        
        
        div0.addEventListener("click",clickHandler0);
        function clickHandler0(e){
            //setTimeOut  有三个参数,第一个是参数:回调函数,第二个参数是多少秒后执行,第三个参数可以传递一个参数进去,
            //之后可以在第一个参数 回调函数中接受  重要
            
            setTimeout(function (div){
                //这养设置透明  整体都会透明
                // div.style.opacity="0.2";
                //当我们点击事件的时候,我们一次让这些元素 没过一秒 背景颜色变成透明的
                div.style.backgroundColor="rgba(255,0,0,0.2)";
            },num*1000,this);
            num++;
        }

        div1.addEventListener("click",clickHandler1);
        function clickHandler1(e){
            setTimeout(function (div){
                div.style.backgroundColor="rgba(0,255,0,0.2)";
            },num*1000,this);
            num++;
        }

        div2.addEventListener("click",clickHandler2);
        function clickHandler2(e){
            setTimeout(function (div){
                div.style.backgroundColor="rgba(0,0,255,0.2)";
            },num*1000,this);
            num++;
        }

    </script>

案例二:综合上面案例,我们可不可以,先让div0变透明,在是div2 ,再是div1呢---那只要把div0 设置捕获阶段触发就好了

<script>

        var div0=document.querySelector(".div0");
        var div1=document.querySelector(".div1");
        var div2=document.querySelector(".div2");
        var num=1;
        
        
        div0.addEventListener("click",clickHandler0,true);
        function clickHandler0(e){
            //setTimeOut  有三个参数,第一个是参数:回调函数,第二个参数是多少秒后执行,第三个参数可以传递一个参数进去,
            //之后可以在第一个参数 回调函数中接受  重要
            
            setTimeout(function (div){
                //这养设置透明  整体都会透明
                // div.style.opacity="0.2";
                //当我们点击事件的时候,我们一次让这些元素 没过一秒 背景颜色变成透明的
                div.style.backgroundColor="rgba(255,0,0,0.2)";
            },num*1000,this);
            num++;
        }

        div1.addEventListener("click",clickHandler1);
        function clickHandler1(e){
            setTimeout(function (div){
                div.style.backgroundColor="rgba(0,255,0,0.2)";
            },num*1000,this);
            num++;
        }

        div2.addEventListener("click",clickHandler2);
        function clickHandler2(e){
            setTimeout(function (div){
                div.style.backgroundColor="rgba(0,0,255,0.2)";
            },num*1000,this);
            num++;
        }

    </script>

onclick事件 它不可以一个事件多个方法,addEventListener可以针对一个对象一个事件多个方法,并且可以使用removeAddEventListener中间

停止某些方法。

onclick事件不能设置捕获和冒泡阶段那个有限addEventListener及是否选定一个被另一个覆盖

onlcikc事件没有自由度,addEventListener可以侦听任何自定义事件--比如chilema onchilema没有

e.Propagation();   阻止冒泡

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #div0{
             100px;
            height:100px;
            background-color: red;
            margin: auto;
            display: flex;
        }
        #div1{
            50px;
            height:50px;
            background-color: chartreuse;
            margin: auto;


        }
    </style>
</head>
<body>
    <div id="div0">
        <div id="div1"></div>
    </div>

    <script>
        var div0=document.querySelector("#div0");
        var div1=document.querySelector("#div1");

        div0.addEventListener("click",clickHandler0);
        div1.addEventListener("click",clickHandler1);

        function clickHandler0(e){
            console.log('aaaa');
        }

        function clickHandler1(e){
            e.stopPropagation();     //阻止冒泡 ,这个我们点击div1的时候  div0的事件就不会被触发了
            console.log('bbb');
        }
    </script>
</body>
</html>

案例:通过给UL添加事件,实现点击li元素添加样式

    <ul>
        <li>吉林</li>
        <li>上海</li>
        <li>北京</li>
    </ul>

    <script>
        //如果给li添加事件,li的条目要是多的话  就会占用多的内存
        //这里给ul添加事件
        var bool=false;
        var ul=document.getElementsByTagName('ul')[0];
        ul.addEventListener("click",clickHandler);
        function clickHandler(e){
            //e.target 是我们点击的目标对象
           e.target.style.backgroundColor="red";
        }
    </script>

案例:

   <!-- <ul>
        <li>吉林
            <ul>
                <li>通辽</li>
                <li>南关</li>
                <li>长春
                    <ul>
                        <li>净月</li>
                        <li>高新</li>
                        <li>经开</li>
                    </ul>
                </li>
                <li>四平</li>
                <li>沈阳</li>
            </ul>
        </li>
        <li>上海
            <ul>
                <li>嘉定</li>
                <li>马路</li>
                <li>虹桥</li>
                <li>安亭</li>
            </ul>
        </li>
        <li>北京
            <ul>
                <li>城西</li>
                <li>人民</li>
                <li>城南</li>
            </ul>
        </li>
    </ul>


    <script>
        var li=document.getElementsByTagName("li");
        for(var i=0;i<li.length;i++){
            li[i].addEventListener('click',clickHandler);
        }

        function clickHandler(e){
            e.stopPropagation();
          this.bool=!this.bool;
          if(this.firstElementChild.style=="null"){
              console.log("aaa");
          }
          if(this.bool){
            this.firstElementChild.style.display="none";
            return;
          }
          this.firstElementChild.style.display="block";
           
        }
    </script> -->
原文地址:https://www.cnblogs.com/xiaowie/p/13669211.html