js-DOM-事件

目录

1.定义

2.事件组成

3.注册/移除事件

[1]注册事件

(1)on关键字

[1]行内式

[2]通过属性绑定的方式注册事件

(2)使用addEventListener来注册事件⭐️⭐️⭐️

[2]移除事件 

4.事件对象

[1]获取触发事件的元素

[2]获取该事件的事件类型

[3]阻止事件的默认行为

 [4]阻止事件的冒泡/捕获

示例

5.事件流

[1]什么事件为冒泡事件;什么事件是捕获事件

[2]阻止事件冒泡/事件捕获

 6.如何理解事件委托

7.事件类型

1)鼠标事件

 鼠标事件中事件对象的属性

示例1: 鼠标移入文本放大展示

 示例2: 禁止打开右侧菜单

2)键盘事件

键盘事件中事件对象的属性

示例1: 京东搜索框案例

示例2: 通过上下左右箭头控制元素移动

3)表单元素的事件

示例2:当输入框获取焦点时,选中输入框中的所有内容

4)窗口/文档/资源事件

4)移动端的触摸事件

5)盒子拖拽事件(html5新增)

6)视频音频事件

7)复制事件

示例1: 当用户想要复制页面内容时,提示开通会员再复制

8.事件阶段


1.定义

事件是指用户的某种行为或浏览器自身执行的某种动作,响应这些动作的代码称为事件处理程序。

JavaScript 通过事件驱动模型允许你为特定事件设置处理函数,当这些事件发生时,相应的处理函数就会被触发执行。

2.事件组成

事件由三部分组成

  • 事件源:给某元素绑定事件,该元素被称为事件源;
  • 事件类型:如点击事件click;
  • 事件处理程序:handler

3.注册/移除事件

[1]注册事件

注册事件有两种方式,一种是使用on关键字来进行事件注册,另一种是通过addEventListener方法进行事件注册。

(1)on关键字

[1]行内式
<element onxxx='执行代码'><element>
<!-- 该div元素点击时会在控制台打印111-->
<div onclick='console.log(111)'>点击打印<div>
<!-- 行内式绑定的是执行代码, 若是绑定方法需要设置为方法的调用!!! -->
<div onclick='toCon()'>点击打印<div>
<script>
  function toCon(){
    console.log(111)
  }
</script>
[2]通过属性绑定的方式注册事件
element.onxxx = function(){...}
const box = document.querySelector('div')
box.onclick = function(){
  console.log(111)
}

使用on关键字注册事件的特点是 如果同一个元素拥有多个相同事件,那么后面的事件会覆盖前面的事件--->也就是说若是使用on关键字注册事件,同一元素不能注册相同的事件!

box.onclick = function () {
    console.log('大家好,我是班长');
}
box.onclick = function () {
    console.log('大家好,我是课代表');
}

 上述代码中当box元素被点击时会在控制台打印'大家好,我是课代表'

(2)使用addEventListener来注册事件⭐️⭐️⭐️

使用addEventListener注册事件,可以实现给一个元素,设置多个相同的事件

(1)语法

element.addEventListener(事件类型,事件方法,true/false)

第三个参数为false那么该事件为冒泡事件,若是为true那么该事件为捕获事件

  • eg注册点击事件
  • function fun1() {
        console.log('大家好,我是班长');
    }
    
    addEventListener('click' fun1,false)

[2]移除事件 

(1)on关键字注册的事件在移除时直接置空;

// 1. 利用on设置事件
box.onclick = function () {
    console.log('我只能打印一次');
    // 点击完之后立刻清空点击事件
    this.onclick = null;
}

(2)addEventListener注册事件使用removeEventListener方法移除事件

function fun() {
    console.log('我只能打印一次');
    // 点击完之后移除事件
    // removeEventListener()
    // add怎么赋值,remove就怎么赋值
    box.removeEventListener('click',fun,false)
}
  • 需要注意:在使用removeEventListener进行事件移除时,需要传入完全相同的参数
  • function myEventHandler(event) {
        // ... 处理逻辑
    }
    
    // 添加
    element.addEventListener('click', myEventHandler);
    
    // 移除 (正确:传入相同的函数引用)
    element.removeEventListener('click', myEventHandler);
    
    // 移除 (错误:传入的是匿名函数,无法移除)
    element.addEventListener('click', () => { console.log('匿名函数'); });
    element.removeEventListener('click', () => { console.log('匿名函数'); }); // 这行无效!

    4.事件对象

    当事件发生时➡️事件处理函数被调用,浏览器会创建一个事件对象,并将其作为参数传递给事件处理函数。这个对象包含了有关事件的详细信息,例如事件类型、目标元素等。

    注意:若是行内式给元素绑定事件时,若是绑定的是方法的调用,需要手动将事件对象event传入,否则获取不到事件对象。

    <a href="https://www.baidu.com/" onclick="bandA()">跳转到百度</a>
    <script>
      function bandA(e){
        console.log(e) // undefined
      }
    </script>
    <!--传递的值必须是event,否则获取不到!-->
    <a href="https://www.baidu.com/" onclick="bandA(e)">跳转到百度</a>
    <script>
      function bandA(e){
        console.log(e) // undefined
      }
    </script>
    <a href="https://www.baidu.com/" onclick="bandA(event)">跳转到百度</a>
    <script>
      function bandA(e){
        console.log(e) // 事件对象
      }
    </script>
    [1]获取触发事件的元素
    e.target

    在这里需要注意e.target与this的区别

    •  this: 事件源也就是绑定事件的元素
    • e.target: 此时被点击的元素
    [2]获取该事件的事件类型
    e.type
    [3]阻止事件的默认行为
    e.preventDefault();
     [4]阻止事件的冒泡/捕获
    e.stopPropagation()
    示例
    <!-- 当点击下述a标签时会跳转到百度首页 -->
    <a href="https://www.baidu.com/">跳转到百度</a>
    <!-- 若是不想跳转,可以阻止a标签的默认行为来阻止a标签跳转 -->
    <a href="https://www.baidu.com/" onclick="bandA(event)">跳转到百度</a>
    <script>
      function bandA(e){
        e.preventDefault()
      }
    </script>

    5.事件流

    当事件发生在具有父元素的元素上,浏览器会经历两个阶段

    • 捕获阶段:事件从 window 对象向下传播到目标元素的父级过程
    • 目标阶段:事件到达目标元素本身
    • 冒泡阶段:事件从目标元素开始向上冒泡回 window 对象

    [1]什么事件为冒泡事件;什么事件是捕获事件

    • 使用on注册的事件是冒泡事件;
    • 使用addEventListener注册的事件
      • 若是第三个参数为false则是冒泡事件;
      • 若是第三个参数为true若是捕获事件;
      • tips:不传第三个参数默认是冒泡事件;

    举例说明

    • 使用onxxx注册事件,默认是冒泡事件 
      <style>
       .out{
         width: 200px;
         height: 200px;
         border: 1px solid red;
       }
       .inner{
         width: 100px;
         height: 100px;
         border: 1px solid red;
       }
      </style>
      <div class="out">
        <div class="inner"></div>
      </div>
      <script>
        // 5.事件流
        const out = document.querySelector('.out')
        const inner = document.querySelector('.inner')
        out.onclick = function(){
         console.log('out')
        }
        inner.onclick = function(){
         console.log('inner')
        }
      </script>

      当点击inner元素时【1】执行目标元素➡️打印inner【2】冒泡➡️打印out

    • 使用addEventListener注册捕获事件       

    • <style>
       .out{
         width: 200px;
         height: 200px;
         border: 1px solid red;
       }
       .inner{
         width: 100px;
         height: 100px;
         border: 1px solid red;
       }
      </style>
      <script>
        // 5.事件流
        const out = document.querySelector('.out')
        const inner = document.querySelector('.inner')
        inner.addEventListener('click', function(){
          console.log('inner')
        },true)
        out.addEventListener('click', function(){
          console.log('out')
        },true)
      </script>
      当点击inner元素时【1】捕获➡️打印out 【2】执行目标元素➡️打印inner

    [2]阻止事件冒泡/事件捕获

    • 即可以阻止事件冒泡又可以阻止事件捕获
      • e.stopPropagation();
    • 阻止事件冒泡
      • e.cancelBubble();

     6.如何理解事件委托

    [1]定义:事件委托简单来说就是:事件不直接绑定在某个元素上而是绑定在该元素的父元素上,进行触发的时候再通过条件进行判断

    [2]优点:

    • 大量节省内存占用减少注册事件
    • 当在新增加子对象时,无需再对齐进性事件绑定,对于动态内容比较友好

    [3]举例说明

    如下,若是我们为li设置点击事件,需要循环设置10个点击事件(但是若是li元素有成千上百个呢,直接为li元素设置点击事件就不太友好了),事件代理仅需设置一个点击事件就可以完成所需功能!

     <ul id="ul">
          <li>1</li>
          <li>2</li>
          <li>3</li>
          <li>4</li>
          <li>5</li>
          <li>6</li>
          <li>7</li>
          <li>8</li>
          <li>9</li>
          <li>10</li>
        </ul>
        <script>
          let ul = document.getElementById('ul')
          ul.onclick=function(e){
              console.log(e.target.innerHTML);
          }
        </script>

    7.事件类型

    注:事件不采用驼峰命名,都是用小写

    1)鼠标事件

    点击事件click
    双击事件dblclick
    鼠标按下事件mousedown
    鼠标释放事件mouseup

    鼠标移入事件-鼠标指针移入元素本身(不冒泡)

    mouseenter

    鼠标移出事件-鼠标指针移出元素本身(不冒泡)

    mouseleave
    鼠标移入事件-鼠标指针移入元素本身/子元素(冒泡)mouseover
    鼠标移出事件-鼠标指针移出元素本身/子元素(冒泡)mouseout
    鼠标在元素/子元素内持续移动时触发mousemove
    鼠标尝试打开上下文菜单时触发contextmenu

     鼠标事件中事件对象的属性

    •  clientX/clientY: 相对于浏览器窗口左上角的鼠标指针的X和Y的坐标
    • pageX/pageY:   相对于页面左上角的鼠标指针的X和Y的坐标

    示例1: 鼠标移入文本放大展示

    <style>
      div{
        width: 200px;
        height: 100px;
        border:1px solid #666;
      }
      .display-font{
        font-size: 20px;
      }
    </style>
    <div onmouseenter="changeSize(event,1)" onmouseleave="changeSize(event, 2)" >详细说明</div>
    <script>
      function changeSize(e, type){
        const box = document.querySelector('div')
        switch(type){
          case 1:
            box.setAttribute('class', 'display-font')
            break
          case 2:
            box.removeAttribute('class')
        }
        
      }
    </script>

     示例2: 禁止打开右侧菜单

    <div>
      <p>我是一个兵,来自老百姓。我是一个兵,来自老百姓。我是一个兵,来自老百姓。我是一个兵,来自老百姓。我是一个兵,来自老百姓。我是一个兵,来自老百姓。我是一个兵,来自老百姓。我是一个兵,来自老百姓。我是一个兵,来自老百姓。我是一个兵,来自老百姓。</p>
    </div>
    <script>
      const pBox = document.querySelector('p')
      pBox.oncontextmenu = function(e){
        // 取消事件的默认行为
        e.preventDefault()
      }
    </script>

    2)键盘事件

    •  [1]键盘按下时触发:onkeydown
      • 当用户按下任意键时立即触发
      • 如果按住某个键不放,keydown 会持续触发(取决于键盘的重复速率设置)
    • [2]键盘弹起时触发: onkeyup
      • 当用户释放按键时触发
      • 每次按键只触发一次,即使用户长时间按住某个键也不会重复触发

    键盘事件中事件对象的属性

    [1]key:返回被按下的键的实际值

       document.addEventListener('keydown', function(e){
         console.log(e.key) // 按下a键则打印a,按下左箭头则打印ArrowLeft
       }, false)

    [2]code:表示物理按键的位置,不受键盘布局影响。

    [3]keycode:返回触发事件的键的 ASCII 值(已被废弃,还支持)

    [4]ctrlKey/shiftKey/altKey/metaKey: 布尔值,判断是否同时按下 CtrlShiftAlt, 或 Windows 键或 Mac 上的 Command 键

    [5]repeat:对于 keydown 事件,如果一个键被持续按下,则该属性为 true,可用于区分长按和短按

    示例1: 京东搜索框案例

    打开京东首页,当点击“s”键时搜索框会自动聚焦。

    <input type="text" placeholder="请输入">
    <script>
       document.addEventListener('keyup', function(e){
         console.log('e.key',e.key)
         if(e.key === 's') {
            // 聚焦搜索框
            const searchBox = document.querySelector('input')
            searchBox.focus()
         }
       }, false)

    在此需要监听keyup事件,若是监听keydown事件 => 在键盘按下的时候就会聚焦,那么s相当于输入到input框中了。

    示例2: 通过上下左右箭头控制元素移动

    在很多游戏中,会通过上下左右箭头控制人物进行移动,其实就是通过监听键盘按下事件实现的。

    <style>
      .screen{
        width: 300px;
        height: 600px;
        border: 1px solid #666;
        padding: 50px;
        position: relative;
      }
      .person{
        width: 30px;
        height: 30px;
        background-color: red;
        position: absolute;
        top:50%;
        left:50%;
        transform: translate(-50%, -50%);
      }
    </style>
    <div class="screen">
      <div class="person"></div>
    </div>
    <script>
      const person = document.querySelector('.person')
      let topL = parseInt(window.getComputedStyle(person).top)
      let leftL = parseInt(window.getComputedStyle(person).left)
      document.onkeydown = function(e){
        switch(e.key){
          case 'ArrowUp':
            if(topL >= 25){
              topL = topL - 10
            } else if(topL<25 && topL>15) {
              topL = 15
            }
            break
          case 'ArrowDown':
            // 边界值top+15 = 700
            if(topL <= 675){
                topL += 10
            } else if(topL>675 && topL<685) {
              topL = 685
            }
            break
          case 'ArrowLeft':
            // left-15 = 0
            if(leftL >= 25){
              leftL = leftL - 10
            } else if(leftL<25 && leftL>15) {
              leftL = 15
            }
            break
          case 'ArrowRight':
            if(leftL <= 375){
                leftL += 10
            } else if(leftL>375 && leftL<385) {
              leftL = 385
            }
            break
        }
        person.style.left = leftL + 'px'
        person.style.top = topL + 'px'
      }
    </script>

    3)表单元素的事件

    inputinput/textarea元素的值发生变化时触发➡️实时响应用户输入的首选
    select用户在input/textarea元素中选中文本时触发
    changeinput/textarea/select元素的值发生改变时触发
    focus表单元素获取焦点时触发
    blur表单元素失去焦点时触发
    submit表单被提交时触发(如点击提交按钮或按回车)。监听在 form元素上,常用 event.preventDefault() 来阻止表单默认提交行为以进行验证。
    reset当表单被重置(点击 type="reset" 的按钮)时触发

    表单元素常用的事件如下:

    示例1:当输入框中内容改变的时候,打印输入框中的内容;

     <body>
        <input type="text" id="input" />
        <script>
          let inputBox = document.getElementById('input')
          inputBox.oninput = function () {
            console.log(inputBox.value)
          }
        </script>
      </body>

    示例2:当输入框获取焦点时,选中输入框中的所有内容

    <input type="text" placeholder="百度一下">
    <script>
      const searchBox = document.querySelector('input')
      searchBox.onfocus = function(){
        if (!searchBox.value){
          searchBox.value = searchBox.placeholder
        }
        searchBox.select()
      }
    </script>

    4)窗口/文档/资源事件

    load当整个页面及所有依赖资源(如样式表、图片)已完成加载时触发

    在window上触发;也可在img/script等标签使用

    DOMContentLoaded

    当初始的 HTML 文档被完全加载和解析完成时触发

    无需等待样式表、图片加载完毕➡️执行初始化逻辑的最佳时机,比 load 更快

    在documents上触发
    resize

    浏览器窗口大小改变时触发

    常用于实现响应式布局调整

    在window上触发
    scroll

    用户滚动页面或元素时触发

    常用于实现无限滚动、导航栏隐藏等效果

    hashchange

    当 URL 的锚部分(即 # 号后面的部分)发生改变

    实现单页面应用 (SPA) 的路由

    在window上触发
    unload

    当用户退出页面时触发

    现在较少使用,更多地转向 beforeunload 来提示用户保存未保存的工作

    beforeunload在即将卸载页面之前触发,允许显示一个确认对话框询问用户是否真的要离开

    4)移动端的触摸事件

    touchstart当手指触摸到一个元素上时触发
    touchend当手指从屏幕上抬起时触发
    touchmove当手指在屏幕上滑动时持续触发
    touchcancel当触摸被意外中断(如来电提示)时触发

    5)盒子拖拽事件(html5新增)

    • [1]盒子拖拽事件
      • 1)开始拖拽:ondragstart
      • 2)拖拽过程中:ondrag
      • 3)结束拖拽:ondragend
    • [2]容器拖拽事件
      • 1)具有拖拽元素进入容器:ondragenter
      • 2)具有拖拽元素的盒子在容器中移动:ondragover
      • 3)具有拖拽元素的盒子离开容器:ondragleave
      • 4)具有拖拽元素的盒子进入容器后松手:ondrop
        • 注:执行4事件必须禁止2事件的默认效果;

    6)视频音频事件

    • [1]视频/音频的开始播放事件:onplay
    • [2]音频/视频的暂停播放事件:onpause

    7)复制事件

    • copy:当用户点击复制时触发
      • 注:若是禁止该事件的默认行为,虽然复制还是可以点击,但是内容并不会被复制成功
    • selectstart:当用户开始选择(选中)页面上的内容时触发的事件

    示例1: 当用户想要复制页面内容时,提示开通会员再复制

     <p>我是一个兵 来自老百姓111</p>
     <script>
      const isMember = 0 // 模拟后端数据非会员
      document.addEventListener('selectstart', function(e){
        if (!isMember){
          alert('请先开通会员再来复制吧~')
          e.preventDefault()
        }
      }, false)
     </script>

    8.事件阶段

    事件分为三大阶段

    • 捕获事件
      • 当某个事件被触发之后,那么它所有的 父元素 相同的事件 也会被触发;
      • 执行顺序:在捕获的过程中,最外层(根)元素的事件先被触发,然后依次向内执行,直到触发最里面的元素(事件源)--->由外到内,由父到子;
    • 目标事件(正常事件)
    • 冒泡事件
      • 当某个元素的事件被触发之后,那么它所有的 父元素 相同的事件 也会被触发
      • 执行顺序:由内到外,从小到大

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值