【Web APIs】事件高级

目录

1.事件对象

1.1获取事件对象

1.2事件对象常用属性

2.事件流

1.1事件流的两个阶段:冒泡和捕获

1.2阻止事件流动

1.3阻止默认行为

1.4两种注册事件的区别

3.事件委托


1.事件对象

1.1获取事件对象

**事件对象:**也是一个对象,这个对象里有事件触发时的相关信息

例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置的信息

获取事件对象:

  • 在事件绑定的回调函数的第一个参数就是事件对象
  • 一般命名为event,ev,e

语法: 元素.addEventListener('click', function(e) { }) e就是事件对象

1.2事件对象常用属性

常用属性

  • type:获取当前事件类型
  • clientX/clientY:获取光标相对于浏览器可见窗口左上角的位置
  • pageX/pageY:获取光标相对于浏览器窗口左上角的位置
  • offsetX/offsetY:获取光标相对于当前DOM元素左上角的位置
  • key:用户按下的键盘键的值(现在不再使用keyNode)

案例:图片跟随鼠标

html 复制代码
<!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>
        img {
            position: absolute;
            top: 0;
            left: 0;
        }
    </style>
</head>
<body>
    <img src="./pictures/tianshi.gif" alt="">

    <script>
        let img = document.querySelector('img')
        document.addEventListener('mousemove', function(e) {
            // 鼠标坐标赋值给图片
            // 减值是为了让鼠标在图片上面
            img.style.left = e.pageX - 50 + 'px'
            img.style.top = e.pageY - 40 + 'px'

        })
        
    </script>
</body>
</html>

2.事件流

1.1事件流的两个阶段:冒泡和捕获

事件流:事件完整执行过程中的流动路径

假设页面里有一个div,当触发事件时,会经历两个阶段:捕获阶段和冒泡阶段

①事件冒泡:

当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发(依次向上调用所有父级元素的同名事件),这一过程称为事件冒泡

📖Note:

  • 事件冒泡是默认存在的

②事件捕获:

从DOM的根元素开始去执行对应的事件(从外到里)

📖Note:

  • 事件捕获需要写对应的代码才能看到
  • DOM.addEventListener(事件类型,事件处理函数,是否使用捕获机制),第三个参数传入true代表是捕获阶段触发(不常用),传入false代表冒泡阶段触发,默认false
  • 若是用L0事件监听,则只有冒泡阶段,没有捕获阶段

捕获:父级到子级 冒泡:子级到父级

html 复制代码
<!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>

        .grand {
            margin: 100px;
            width: 500px;
            height: 500px;
            background-color: red;
        }

        .father {
            width: 400px;
            height: 400px;
            background-color: pink;
        }
        .son {
            width: 200px;
            height: 200px;
            background-color: skyblue;
        }


    </style>
</head>
<body>

    <div class="grand">
        <div class="father">
            <div class="son"></div>
        </div>
    </div>

    <script>
        let grand = document.querySelector('.grand')
        let father = document.querySelector('.father')
        let son = document.querySelector('.son')

        grand.addEventListener('click', function(e) {
            alert('爷爷级元素的点击事件')
        })

        father.addEventListener('click', function() {
            alert('父级元素的点击事件')
        })

        son.addEventListener('click', function() {
            alert('子级元素的点击事件')
        })

        
    </script>
</body>
</html>

上面的案例中,当点击子级元素时,先触发子级元素的绑定的点击事件,再依次向上触发父级元素绑定的点击事件,依次类推,直到访问完所有的父级元素,这个过程即为事件冒泡

事件捕获的过程同理:只不过是从根元素向下访问所有的子级元素

1.2阻止事件流动

冒泡模式默认存在,可能会导致事件影响到父级元素;若想把事件限制在当前元素内,就要阻止事件流动

语法: 时间对象.stopPropagation()

📖Note:

  • 阻止事件流动需要拿到事件对象,因此回调函数的形参列表必须写e/event

上面的案例中:组织事件流动后,当点击子级元素时,只触发子级元素的点击事件,不会触发父级元素的点击事件

**📖Note:**鼠标经过事件

  • mouseover和mouseout会有冒泡效果
  • mouseenter和mouseleave没有冒泡效果(推荐)

1.3阻止默认行为

默认行为,比如链接点击不跳转,表单域的跳转

语法: e.preventDefault()

1.4两种注册事件的区别

两种注册事件的区别:

传统on注册(L0)

  • 同一个对象,后面注册的事件会覆盖前面注册(同一个事件)
  • 直接使用null覆盖偶就可以实现事件的解绑
  • 都是冒泡阶段执行的

事件监听注册(L2)

  • 语法: addEventListener(事件类型, 事件处理函数, 是否使用捕获)、
  • 后面注册的事件不会覆盖前面注册的事件(同一个事件)
  • 可以通过第三个参数去确定是在冒泡或者捕获阶段执行
  • 必须使用removeEventListener(事件类型, 事件处理函数, 获取捕获或者冒泡阶段)
  • 匿名函数无法被解绑

3.事件委托

利用事件流的特征解决一些开发需求

场景:多个子级元素进行同样的操作时,可以将这个操作委托给父级元素;比如所有的子级元素都要绑定点击事件,则可以给它们的父级添加点击事件,由于冒泡模式默认存在,所以当自身没有绑定点击事件时,会触发父级的点击事件

获取点击的对象,语法:e.target

获取点击的对象的名字,语法:e.target.tagName

相关推荐
老码沉思录1 小时前
写给初学者的React Native 全栈开发实战班
javascript·react native·react.js
我不当帕鲁谁当帕鲁1 小时前
arcgis for js实现FeatureLayer图层弹窗展示所有field字段
前端·javascript·arcgis
那一抹阳光多灿烂1 小时前
工程化实战内功修炼测试题
前端·javascript
爱吃生蚝的于勒1 小时前
C语言内存函数
c语言·开发语言·数据结构·c++·学习·算法
小白学大数据3 小时前
Python爬虫开发中的分析与方案制定
开发语言·c++·爬虫·python
冰芒猓4 小时前
SpringMVC数据校验、数据格式化处理、国际化设置
开发语言·maven
失落的香蕉4 小时前
C语言串讲-2之指针和结构体
java·c语言·开发语言
红中马喽4 小时前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习
杜杜的man4 小时前
【go从零单排】Closing Channels通道关闭、Range over Channels
开发语言·后端·golang
java小吕布5 小时前
Java中Properties的使用详解
java·开发语言·后端