事件

本文详细介绍了JavaScript中的事件,包括事件的基本概念、事件对象、点击事件的坐标获取(offsetX/Y, clientX/Y, pageX/Y)、常见事件类型、事件绑定方式(事件属性、事件绑定、事件监听)以及事件的执行机制(事件传播、事件目标对象、事件委托)。还探讨了如何阻止事件传播和阻止默认行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

事件

JavaScript事件

一、JavaScript事件简介

  1. 什么叫事件

当我们点击一个按钮的时候,会弹出一个对话框。在JavaScript中,“点击”这个事情就看做一个事件。“弹出对话框”其实就是我们在点击事件中做的一些事

  1. 事件该有的3部分

    1. 事件源:触发谁的事件

    2. 事件类型:

      • 这个事件是干啥的,是点击呢,还是移动呢
    3. 事件处理函数

      var odiv = document.querySelector('div')
      div.onclick = function(){}
      //谁来触发事件 → odiv → 这个事件的事件源就是odiv
      //触发什么事件 → onclick →这个事件类型就是click
      //触发了之后做什么 → function(){} → 这个事件处理的函数
      

二、事件对象event

  1. 每触发一个事件都会生成事件对象

  2. 事件对象包含对事件的描述信息

    • 你触发一个点击事件的时候,你点了哪个位置,坐标是多少
    • 你触发了一个键盘事件,你按的是哪个按钮
  3. 获取事假对象

    • 在每一个事件处理函数的形参位置,默认第一个就是事件对象

      oDiv.onclick = function(e){
          console.log(e)
      }
      
    • IE兼容性写法:

      oDiv.onclick = function (e){
          e = e || window.event
          console.log(e)
      }
      

三、点击事件的光标点获取

  • 每一个点击事件的坐标点都不是一对,因为要有一个相对的坐标系
    • 相对事件源(你点击的元素)
    • 相对页面
    • 相对浏览器窗口
  1. 相对事件源(你点击的元素)offsetX offsetY

    • 是相对于你点击的元素的边框内侧开始计算

      • offsetXoffsetY
      <style>
          *{margin:0; padding:0;}
          div{
              width: 300px;
              height:300px;
              padding:20px;
              border;10px solid red;
              margin:20px 0 0 30px;
          }
      </style>
      <body>
          <div></div>
          <script>
              var oDiv = document.querySelector('div')
              //绑定点击事件
              oDiv.onclick = function(e){
                  //事件对象兼容写法
                  e = e || window.event
                  console.log(e.offsetX)
                  console.log(e.offsetY)
              }
          </script>
      </body>
      
  2. 相对于浏览器窗口clientX clientY

    • 是相对于浏览器窗口计算,不管你页面滚动到什么情况,都是根据窗口来计算坐标

      • clientXclientY

        <style>
            *{margin:0;padding:0;}
            body{
                width:2000px;
                height:2000px;
            }
            div{
                width:300px;
                height:300px;
                padding:20px;
                border:10px sosid red;
                margin:20px 0 0 30px;
            }
        </style>
        <body>
            <div></div>
            <script>
                var oDiv = document.querySelector('div')
                //绑定点击事件
                oDiv.onclick = function(e){
                    //事件对象兼容写法
                    e = e || window.event
                    console.log(e.clientX)
                    console.log(e.clientY)
                }
            </script>
        </body>
        
  3. 相对于页面pageX pageY

    • 是相对于整个页面的坐标点,不管有没有滚动,都是相对于页面拿到的坐标

      • pageXpageY

        <style>
            *{margin:0;padding:0;}
            body{
                width:2000px;
                height:2000px;
            }
            div{
                width:300px;
                height:300px;
                padding:20px;
                border:10px sosid red;
                margin:20px 0 0 30px;
            }
        </style>
        <body>
            <div></div>
            <script>
                var oDiv = document.querySelector('div')
                //绑定点击事件
                oDiv.onclick = function(e){
                    //事件对象兼容写法
                    e = e || window.event
                    console.log(e.pageX)
                    console.log(e.pageY)
                }
            </script>
        </body>
        

四、常见的事件(了解)

  1. 浏览器事件

    • load: 页面全部资源加载完毕
    • scroll 浏览器滚动时触发
    • resize 页面大小事件
  2. 鼠标事件

    • click 点击事件

    • dbclick双击事件

    • contextmenu左键单击事件

    • mousedown鼠标左键按下事件

    • mouseup鼠标左键抬起事件

    • mousemove鼠标移动事件

    • mouseover鼠标移入事件

    • mouseout鼠标移出事件

    • mouseenter鼠标移入事件

    • mouseleave鼠标移出事件

      • mouseovermouseenter 区别

      • onmouseoveronmouseout:鼠标经过时自身触发事件,经过其子元素时也触发该事件;(父亲有的东西,儿子也有) ,支持冒泡

        onmouseenteronmouseleave:鼠标经过时自身触发事件,经过其子元素时不触发该事件。(父亲的东西就是父亲的,不归儿子所有) ,不支持冒泡

  3. 键盘事件

    • keyup 键盘抬起事件
    • keydown 键盘按下事件
    • keypress 键盘按下抬起事件
  4. 表单事件

    • change 表单内容改变事件
    • input 表单内容输入事件
    • submit 表单提交事件
  5. 触摸事件

    • touchstart 触摸开始事件
    • touchend 触摸结束事件
    • touchmove 触摸移动事件
  6. 焦点事件

    • onblur 失去焦点
    • onfocus 获取焦点

五、事件

鼠标事件

鼠标移入移出改变样式(效果类型于css中的hover)

//鼠标移入
div.onmouseover = function(){
    div.style.backguound = 'red'
}
//鼠标移出
div.onmouseover = function(){
    div.style.backguound = 'blue'
}
键盘事件

只能给在页面上选中的元素(表单元素)和document来绑定键盘事件

注:不能给页面上的一个div元素设置键盘事件

document.onkeyup = function(){...}
oInput.onkeyup = function(){...}
确定按键
  • 我们的键盘上每一个按键都有一个自己独立的编码

  • 我们就是靠这个编码来确定我们按下的是哪个按键的

  • 我们通过事件对象 . keyCode 或者事件对象 . which 来获取

  • FireFox2.0不支持keyCode ,所有要用which

document.addEventListener('keydown', function (e) {
        //事件对象的兼容写法
        e = e || window.event
        //获取键盘码的兼容写法
        var keyCode = e.keyCode || e.which
        console.log(keyCode)
    })
//按下哪个键,控制台输出相应的键码

常见键码(了解)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gbe39Uvs-1628316746982)(C:\Users\song\AppData\Local\Temp\1628253509931.png)]

回车键案例

document.onkeydown = function(e){
    //如果是回撤键,执行登录方法
    //兼容写法
    e = e || window.event
    let keyCode = e.keyCode || e.which || e.charCode
    //判断是否按下回车键
    if(keyCode == 13){
        location.href = 'http://www.jd.com'
    }
}

组合按键

  • 组合按键最主要的就是 alt/shift/ctrl 三个按键

  • 在我点击某一个按键的时候判断一下这三个按键有没有按下,有就是组合了,没有就是没有组合

  • 事件对象里也为我们提供了三个属性

    • altKey :alt键按下得到true,否则得到false
    • shiftKey :shift键按下得到true,否则得到false
    • ctrlKey:ctrl键按下得到true,否则得到false
  • 我们就可以通过这三个属性来判断是否都按下了

     document.onkeyup = function (e) {
            e = e || window.event
            let keyCode = e.keyCode || e.which
            if (e.altKey && keyCode === 65) {
                alert('你按下了alt和a')
            }
        }
    

六、事件的绑定方式

事件属性
  • 把事假写在标签里面

    • 好处:大家都会,几乎所有的浏览器都支持

    • 坏处:夹杂在HTML代码中,代码不简介;这种事件写法效率不高;不符合“行为,样式,结构”相分离

      <inpute type="button" onclick="alertMessage" value="按钮"
      
事件绑定
  • 缺点: 只能给一个元素注册一个事件,绑定一个事件,后一个会覆盖前一个

  • 好处: “行为,样式,结构”相分离;便于操作;方便读取事件对象

    <div id="div">事件绑定</div>
    <script>
        div.onclick = function(){
            alert('我是第一个事件')
        }
         div.onclick = function(){
            alert('我是第二个事件')
        }
    </script>
    //当你点击的时候,只会执行第二个,第一个就没有了,被覆盖掉了
    
事件监听

addEventListener 非IE7 8下使用

语法: 元素.addEventListener('事件类型',事件处理函数,冒泡还是捕获)

<div id="div">事件绑定</div>
<script>
    div.addEventListener('click',function(){
        alert('我是第一个事件')
    },false)
     div.addEventListener('click',function(){
        alert('我是第二个事件')
    },false)
</script>
//当你点击div的时候,两个函数都会执行,并且会按照你绑定的顺序执行
//先打印 我是第一个事件 ,在打印 我是第二个事件
//注意:事件类型的时候不要写on,点击事件是click,不是onclick

attchEvent IE7 8 下使用

语法: 元素.attachEvent('事件类型',事件处理函数)

<div id="div">事件绑定</div>
<script>
    div.attachEvent('onclick',function(){
        alert('我是第一个事件')
    })
     div.attachEvent('click',function(){
        alert('我是第e二个事件')
    })
</script>
//当你点击div的时候,两个函数都会执行,并且会按照你绑定的顺序执行
//先打印 我是第二个事件,再 打印我是第一个事件
//注意:事件类型的时候要写on,点击事件就是onclick
两个方式的区别
  • 注册事件的时候事件类型参数的书写
    • addEventListener 不用写on
    • attachEvent 要写on
  • 参数个数
    • addEventListener 一般是三个参数,第三个参数可以不写,默认为false,事件冒泡
    • attachEvent 两个参数
  • 执行顺序
    • addEventListener 顺序注册,顺序执行
    • attachEvent 顺序注册,倒序执行
  • 使用浏览器
    • addEventListener 非IE7 8 浏览器
    • attachEvent IE7 8 浏览器

七、事件的执行机制

1.事件的传播

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r2mibJDQ-1628316747005)(C:\Users\song\AppData\Local\Temp\1628299520038.png)]

我们点击在红色盒子生上的同时,也是点在了粉色盒子上,那么两个盒子的点击事件都会触发,这个就叫做 事件的传播

  • 当元素触发一个事件的时候,其父元素也会触发相同的事件,父元素上的父元素也会触发相同的事件
  • 就像上面的图片一样
  • 点击在红色盒子上的时候,会触发红色盒子的点击事件
  • 也是点击在了粉色盒子上,也会触发粉色盒子的点击事件
  • 也是点击在了body上,也会触发body的点击事件
  • 也是点击在了HTML上,也会触发HTML的点击事件
  • 也是点击在document上,也会触发document上的点击事件
  • 也是点在了window上,也会触发window的点击事件
  • 也就是说,页面上的任何一个元素触发事件,都会一层一层最终导致window的相同事件触发前提是各层级元素得有注册相同的事件,不然不会触发

在事件传播的过程中,有一些注意的点:

  1. 只会传播同类事件
  2. 只会从点击元素开始按照HTML的结构逐层向上元素的事件被触发
  3. 内部元素不管有没有改事件,主要上层元素有改事件,那么上层元素的事件就会被触发
2.事件传播方向
  • 事件确定会从自己开始,到window的所有相同事件都会触发
  • 是因为我们点在自己身上,也确定逐层的点在了直至window的每一个元素身上
  • 但是到底是先点在自己身上,还是先点在了window身上呢?
  • 先点在自己身上,就是先执行自己身上的事件处理函数,逐层向上最后执行window的事件处理函数
  • 反之,则是先执行window的事件处理函数,逐层向下,最后执行自己身上的事件处理函数

目标: 你是点击在哪个元素身上,那么这个事件的 目标 就是什么

事件冒泡

  • 就是从事件 目标 的事件处理函数,依次向外,直到window的事件处理函数触发,也就是从下向上的执行事件处理函数
  • 特点: 事件传播方向,有内向外传

事件捕获

  • 就是从 window 的事件处理函数开始,依次向内,直到事件 目标 的事件处理函数执行,也就是从上向下的执行事件处理函数

事件原型图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tPQggiwD-1628316747009)(C:\Users\song\AppData\Local\Temp\1628300952936.png)]

实现:事件捕获和事件冒泡

  • addEventListener 的第三个参数决定了是事件捕获还是事假冒泡
    • false:表示注册的事件在冒泡阶段触发-----默认值
    • true:表示注册的事件在捕获阶段触发
3.事件目标对象target

target 这个属性是事件对象里面的属性,表示你点击的目标

当你触发点击事件的时候,你点击在哪个元素上,target就是哪个元素

这个target也不兼容,在IE 下要用srcElement

<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        //获取ul元素
    	var Ul = document.querySelector('ul')
        //给ul设置点击事件
        Ul.addEventListener('click',function(e){
            e = e || window.event
            var target = e.target || e.srcElement
            console.log(target)
        })
    </script>
</body>
//当你点击ul的时候,target就是ul
//当你点击在li上面的时候,target就是li
4.事件委托

上面这个代码,当你点击li的时候,也可以触发ul 的点击事件

并且在事件内部,我们也可以拿到你点击的到底是ul 还是li

这个时候,我们就可以吧li的事件委托给ul 来做

<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        //获取ul元素
    	var ul = document.querySelector('ul')
        //绑定点击事件
        ul.addEventListener('click',function(e){
            e = e || window.event
            var target = e.target || e.srcElement
            //判断你点击的是li
            if(target.nodeName =='LI'){
                //判断你点击的是li
               console.log('我是li,我被点击了')
            }
        })
    </script>
</body>
//上面的代码,我们就可以把li要做的事件委托给ul来做
  • 为什么要用事件委托

    • 我网页上本身没有li
    • 我们通过代码添加了一些li
    • 添加进来的li是没有点击事件的
    • 我每次动态的操作完li之后,要重新给li绑定一次点击事件,比较麻烦
    • 这个时候只要委托给ul就可以了
    • 因为新加进来的li也是ul的子元素,点击的时候也可以触发ul的点击事件
  • 事件委托的书写

    • 元素的事件只能委托给结构父级或者再结构父级的同样事件上
    • li的点击事件,就不能委托给ul的鼠标移入事件
    • li的点击事件,只能委托给ul或者在更高父级的点击事件上
5.阻止事件传播

e.stopPropagstion() 标准浏览器

e.cancelBubble=true IE低版本

兼容写法

if(e.stopPropagation){
    e.stopPropagation()
}else{
    e.cancelBubble=true
}
6.默认行为
阻止默认行为

有时候,我们不希望浏览器执行默认事件

比如我给a 标签设置了一个点击事件,我点击的时候希望你告诉我你的地址是什么

而不是直接跳转链接

那么,我们就要把a 标签原先的默认事件阻止,不让他执行默认事件

两个方法来阻止默认事件

e.preventDefault(): 非 IE 使用

e.returnValue = false :IE 使用

<a href = "https://www.jd.com" >我是一个链接</a>
<script>
    var a = document.querySelector('a')
a.addEventListener('click',function(e){
    e = e || window.event
    console.log(this.href)
    e.preventDefault ? e.preventDefault() : e.returnValue = false
})
</script>    
  • 这样写完以后,你点击a标签的时候,就不会跳转链接了
  • 而是会在控制台打印a标签的href属性的值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值