JS事件详解

前言

JavaScript 事件
  HTML 事件是发生在 HTML 元素上的事情。
  当在 HTML 页面中使用 JavaScript 时, JavaScript 可以触发这些事件。
HTML 事件
  HTML 事件可以是浏览器行为,也可以是用户行为。
以下是 HTML 事件的实例:
  HTML 页面完成加载
  HTML input 字段改变时
  HTML 按钮被点击
通常,当事件发生时,你可以做些事情。
  在事件触发时 JavaScript 可以执行一些代码。
HTML 元素中可以添加事件属性,使用 JavaScript 代码来添加 HTML 元素。

1 事件初识

事件可以用于处理表单验证,用户输入,用户行为及浏览器动作:
  页面加载时触发事件
  页面关闭时触发事件
  用户点击按钮执行动作
  验证用户输入内容的合法性
  等等 …

<body>
    <button id="btn">点击</button>
</body>
<script>
    //节点.on事件名 = 匿名函数  
    document.getElementById("btn").onclick=function(){
       alert("大海都是水")
    }
</script>

2 为一个元素绑定多个事件(以鼠标点击事件为例)

绑定单个事件,写多个时,后面的会覆盖前面的:
节点.on事件名 = 匿名函数
绑定多个事件,写多个时,事件按顺序执行:
节点.attachEvent(“有on类型的事件/on事件名”,事件处理的函数,false) (谷歌、火狐不支持 IE8以下的浏览器支持 )
节点.addEventListener(“没有on的事件类型/事件名”,事件处理的函数,false)(谷歌、火狐支持 IE8以下不支持)

<body>
    <button id="btn">点击</button>
</body>

2.1 为一个元素绑定单个事件

2.1.1 节点.on
<script>
    //节点.on事件名 = 匿名函数  
    document.getElementById("btn").onclick=function(){
       alert("大海都是水")//没有正常输出显示
    }
    document.getElementById("btn").onclick=function(){
       alert("大海都是水001")//输出显示
    }
</script>

2.2 为元素绑定多个事件:有两种写法

绑定多个事件的意思是可单可多
true - 事件句柄在捕获阶段执行
false- false- 默认。事件句柄在冒泡阶段执行(false可写可不写)

2.2.1 节点.attachEvent()(非主流用法)

谷歌不支持 火狐不支持IE8以下的浏览器支持

<script>
    var btn = document.getElementById("btn")
    btn.attachEvent("onclick",function(){
       console.log("大海全是水")//测试使用的谷歌浏览器,无法输出
    })
</script>
2.2.2 节点.addEventListener()

谷歌支持 火狐支持 IE8以下不支持 (支持目前的主流浏览器)

<script>
    var btn=document.getElementById("btn")
    btn.addEventListener("click",function(){
       alert("大海全是水")//输出显示
    },false)
    btn.addEventListener("click",function(){
        alert("大海全是水001")//输出显示
    },false)
</script>
2.2.3 attachEvent和addEventListener之间的区别

相同点: 都可以为元素绑定事件
不同点:
   1)方法名不一样
   2)参数的个数是不一样的 attachEvent是两个参数 addEventListener是三个参数
   3)addEventListener 谷歌 火狐 IE8 支持 attachEvent IE8以下支持
   4)this指向不同 attachEvent中的指向是window addEventListener表示的是当前绑定事件的对象
   5)一个加on 一个不加on

2.3 为元素绑定事件的兼容写法

<script>
    var btn=document.getElementById("btn")
    //为任意元素绑定事件 事件类型和事件处理函数
    function addEventListener(element,type,fn){//元素,事件类型,匿名函数
        //判断浏览器是否支持这个方法  谷歌 火狐 IE>8
        if(element.addEventListener){
            element.addEventListener(type,fn,false)  //节点.addEventListener()
        }else if(element.attactEvent){
            //iE<=8
            element.attactEvent("on"+type,fn)  //节点.attachEvent()
        }else{
            element["on"+type]=fn    //节点.οnclick=function(){}
        }
    }
    addEventListener(btn,"click",function(){
       alert("大海全是水")
    })
    addEventListener(btn,"click",function(){
       alert("大海全是水001")
    })
</script>

3 为一个元素解除绑定事件

(节点对象/元素对象)节点类和元素类在继承的原型中是相关的

3.1 解绑事件(on)

对象.on事件名 = 事件处理函数
对象.on事件名 = null

3.2 解绑事件(attactEvent())

对象.attactEvent(“on的事件类型”,命名函数)
对象.detachEvent(“on的事件类型”,命名函数)

3.3 解绑事件(addEventListener())

对象.addEventListener(“不加on的事件类型”,命名函数,false)
对象.removeEventListener(“不加on的事件类型”,命名函数,false)

    btn2.onclick=function(){
        //移出绑定事件
        btn.onclick=null;
        btn.detachEvent("click",fn1);
        btn.removeEventListener("click",fn1,false);
    }

3.4 解绑事件的兼容写法

  经测试on的解绑必须写前面才能兼容全部,否则只执行remove的解绑(就无法解绑on的事件)。

<script>
    var btn=document.getElementById("btn")
    //为任意元素绑定事件 事件类型和事件处理函数
    function addEventListener(element,type,fn){//元素,事件类型,匿名函数
        //判断浏览器是否支持这个方法  谷歌 火狐 IE>8
        if(element.onclick){
            element["on" + type] = null
            //console.log("调用了on的解绑");
        }
        else if (element.removeEventListener) {
            element.removeEventListener(type,fnName,false)
            //console.log("调用了remove的解绑");
            //btn1.click(fn1);若是这种绑定倒是可以
        } 
        else  {
            element.detachEvent("on" + type, fnName)
            //console.log("调用了data的解绑");
        }  
    }
    addEventListener(btn,"click",function(){
       alert("大海全是水")
    })
    addEventListener(btn,"click",function(){
       alert("大海全是水001")
    })
</script>

4 事件冒泡

事件冒泡: 多个元素嵌套 有层次关系 这些元素都注册了相同的事件 如果里边的元素事件触发了 外边的元素的事件就会自动触发(从内到外)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #div1{
            width:300px;
            height:200px;
            background-color: red;
        }
        #div2{
            width:250px;
            height:150px;
            background-color: green;
        }
        #div3{
            width:200px;
            height:100px;
            background-color: blue;
        }
    </style>
</head>
<body>
   <div id="div1">
       <div id="div2">
           <div id="div3"></div>
       </div>
   </div> 
</body>
<script>
  function $(id){
    return document.getElementById(id)
}
  $("div1").onclick=function(){
      console.log(this.id)   //div1
  }
  $("div2").onclick=function(){
      console.log(this.id)   //div2
  }
  $("div3").onclick=function(){
      console.log(this.id)   //div3
  }
</script>
</html>
点击顺序是从蓝=>绿=>红

在这里插入图片描述

输出顺序是:点蓝色:div3 div2 div1
      点绿色:div2 div1
      点红色:div1

5 事件捕获

事件捕获: 多个元素嵌套 有层次关系 这些元素都注册了相同的事件 事件触发的形式是由外到内

<script>
  function $(id){
    return document.getElementById(id)
  }
  $("div1").addEventListener("click",function(){
     console.log(this.id)
  },true)

  $("div2").addEventListener("click",function(){
     console.log(this.id)
  },true)

  $("div3").addEventListener("click",function(){
     console.log(this.id)
  },true)
</script>
点击顺序是从蓝=>绿=>红

在这里插入图片描述
输出顺序是:点蓝色:div1 div2 div3
      点绿色:div1 div2
      点红色:div1

总结: addEventListener第三个参数的作用 false 冒泡 true捕获
问题 如果多个事件作用于同一个节点 相互的事件会影响 有些时候不需要这些影响 阻止事件冒泡和捕获

6 阻止事件冒泡

如何阻止事件冒泡
IE浏览器特有的 谷歌火狐不支持 window.event.cancelBubble=true
e.stopPropagation() 谷歌和火狐支持

<script>
      function $(id){
         return document.getElementById(id)
      }
      $("div1").addEventListener("click",function(d){
         console.log(this.id)
        //  d.stopPropagation();
      },false)

      $("div2").addEventListener("click",function(e){
         console.log(this.id)
        //  e.stopPropagation();
      },false)

      $("div3").addEventListener("click",function(e){
         console.log(this.id)
         //阻止事件冒泡
        //  e.stopPropagation();
       },false)
</script>

7 (获取/得知)事件阶段

可以通过e.eventPhase这个属性知道当前的事件是什么阶段的
  eventPhase 属性返回事件传播的当前阶段。它的值是下面的三个常量之一,它们分别表示捕获阶段、正常事件派发和起泡阶段:
            1 事件捕获阶段 由外到内
            2 事件目标阶段 最开始选择的那个
            3 事件冒泡阶段 从里到外

<script>
    function $(id) {
        return document.getElementById(id)
    }
    var objs = [$("div1"), $("div2"), $("div3")]
    //遍历注册事件
    for (var i in objs) {
        console.log(i)
        objs[i].addEventListener("click", function (e) {
            console.log(this.id + "=======>" + e.eventPhase)
        }, false)//false 冒泡 true捕获
        // objs[i].οnclick= function (e) {//事件冒泡
        //     console.log(this.id + "=======>" + e.eventPhase)
        // }
    }
</script>

8 为一个元素绑定多个指向同一事件

为同一个元素绑定多个不同的事件 指向相同的事件处理函数

<body>
    <input type="button"  id="btn" value="金老师"  >
     
</body>
<script>
    function $(id) {//这个其实就是jquery常用的$符号的由来
        return document.getElementById(id)
    }
    $("btn").onclick    = f1
    $("btn").onmouseover= f1
    $("btn").onmouseout = f1
    function f1(e){
          //e.type能够获取事件类型
          switch (e.type){
           case "click":
              console.log("0001")
           break;
           case "mouseover":
               console.log("002")
             break;
           case "mouseout":
               console.log("003")
             break;
        }
    }
</script>

或者用addEvenListener():

    <style>
        #demo{
            width:500px;
            height:500px;
            background-color: red;
        }
    </style>
</head>
<body>
    <div id="demo"></div>
</body>
<script>
    var demo=document.getElementById("demo")
    demo.addEventListener("click",function(){
        console.log("click")
    },false)

    demo.addEventListener("mousemove",function(){
        console.log("mousemove")
    },false)

    demo.addEventListener("mouseout",function(){
        console.log("mouseout")
    },false)
</script>

9 总结

   一 关于事件阶段
   1 事件捕获阶段  由外到内  
   2 事件目标阶段  最开始选择的那个
   3 事件冒泡阶段  从里到外
  
   二 阻止事件冒泡
   为元素绑定事件 
   addEventListener
   事件触发的过程中 可能会出现事件冒泡 为了阻止事件冒泡

      window.event.cancelBubble=true  
      window.event就是一个对象,是IE的标准  

      e.stopPropagetion() 阻止事件冒泡 ------ 谷歌火狐标准

   window.event 和e都是事件参数对象 一个是IE标准 一个是火狐和谷歌标准


  三 一般情况默认的都是冒泡 很少用捕获
    可以通过 e.eventPhase 这个属性能够知道现在事件所处的阶段 
    冒泡阶段: 从里到外
    捕获阶段: 从外向里
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值