【Web APIs】事件高级

发布于:2024-03-29 ⋅ 阅读:(11) ⋅ 点赞:(0)

目录

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)

案例:图片跟随鼠标 

<!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事件监听,则只有冒泡阶段,没有捕获阶段

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

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

本文含有隐藏内容,请 开通VIP 后查看