js-DOM-事件

目录

1.定义

2.事件组成

3.注册/移除事件

[1]注册事件

(1)on关键字

[1]行内式

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

(2)使用addEventListener来注册事件

[2]移除事件 

4.事件对象

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

[2]获取引用触发事件的 DOM 元素

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

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

5.事件类型

1)表单元素的事件

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

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

2)鼠标事件

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

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

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

3)键盘事件

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

示例1: 京东搜索框案例

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

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

5)视频音频事件

6)值改变事件

7)窗口事件

8)复制事件

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

6.事件阶段

执行顺序

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

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

7.如何理解事件代理


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关键字,那么后面的事件会覆盖前面的事件--->也就是说若是使用on关键字注册事件,同一元素不能注册相同的事件!

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

(2)使用addEventListener来注册事件

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

(1)语法

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)
}

    4.事件对象

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

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

    <a href="https://www.baidu.com/" onclick="bandA()">跳转到百度</a>
    <script>
      function bandA(e){
        console.log(e) // undefined
      }
    </script>
    <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.type
    [2]获取引用触发事件的 DOM 元素
    • 事件处理函数中的this指向事件源(绑定事件的元素)
    • 事件对象中存在一个target属性指向被点击的元素
      •  
        e.target
    [3]阻止事件的默认行为
    e.preventDefault();

    示例

    <!-- 当点击下述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>
    [4]阻止事件冒泡/捕获
    e.stopPropagation();

    5.事件类型

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

    1)表单元素的事件

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

    • [1]表单元素值改变事件: input;

    • [2]input元素值选中事件:select

    • [3]获得焦点事件--主要用于表单:foucs

    • [4]失去焦点事件:blur

    • [5]表单被重置:reset

    • [6]表单被提交:submit

    • [7]值改变事件:change

      • 单选框选择某一项时触发。复选框选择某一项时触发。下拉列表选择某一项时触发

    • [8]点击事件:click

    示例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>

    2)鼠标事件

    • [1]鼠标点击事件 :click
    • [2]鼠标双击事件:dblclick
    • [3]鼠标移入时触发:mouseenter
      • 当鼠标指针进入元素时触发
      • mouseover也是当鼠标指针进入元素时触发,与mouseenter的区别是mouseenter不会冒泡,mouseover会冒泡 => 它也会在子元素上触发
    • [4]鼠标移出时触发:mouseleave
      • 当鼠标指针离开元素时触发
      • mouseout也是当鼠标指针离开元素时触发,与mouseleave的区别是mouseleave不会冒泡,mouseout会冒泡 => 它也会在子元素上触发
    • [5]鼠标移动事件:mousemove
      • 当鼠标指针在元素内移动时持续触发 => 是一个持续触发得过程(考虑性能问题)
    • [6]鼠标按下事件:mousedown
    • [7]鼠标弹起事件:mouseup
    • [8]鼠标尝试打开右菜单: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>

    3)键盘事件

    • [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>

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

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

    5)视频音频事件

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

    6)值改变事件

    • 值改变:onchange
    • input标签值改变:oninput

    7)窗口事件

    • load:当整个页面(包括所有的资源:图片、样式表等)加载完成时触发。
    • unload:当用户退出页面时触发(现在较少使用,更多地转向 beforeunload 来提示用户保存未保存的工作)。
    • beforeunload:在即将卸载页面之前触发,允许显示一个确认对话框询问用户是否真的要离开。
    • resize:当浏览器窗口大小改变时触发。
    • scroll:当用户滚动页面或元素时触发。

    8)复制事件

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

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

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

    6.事件阶段

    事件分为三大阶段

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

    执行顺序

    从上往下开始执行;

    • 先执行捕获阶段;
    • 再执行目标阶段;
    • 再执行冒泡阶段

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

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

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

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

    7.如何理解事件代理

    [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>

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值