js教程(8)

本文详细介绍了JavaScript中事件流的概念,包括冒泡阶段和捕获阶段的工作原理,以及如何利用事件冒泡实现事件委托。同时讲解了如何阻止事件冒泡和默认行为,以及解绑事件的不同方法。
摘要由CSDN通过智能技术生成

一、事件流

1.概述

        在JavaScript中,事件流描述的是事件在DOM结构中传播和被处理的顺序。事件流分为冒泡阶段和捕获阶段。

        冒泡阶段(Bubbling Phase):事件首先从最内层的元素开始向父级元素传播,一直传播到最外层的元素。在这个阶段,事件是从内向外传播的。

        捕获阶段(Capturing Phase):与冒泡相反,事件从最外层的元素开始传播,一直传播到最内层的元素。在这个阶段,事件是从外向内传播的。

         事件的传播过程:

  1. 捕获阶段:事件从根元素传播到目标元素,依次触发每个元素上绑定的捕获事件处理程序。
  2. 目标阶段:事件到达目标元素,触发目标元素上绑定的事件处理程序。
  3. 冒泡阶段:事件从目标元素开始向上冒泡,依次触发每个元素上绑定的冒泡事件处理程序。

        在实际开发中,事件处理程序一般是绑定在目标元素上,通过事件冒泡机制,可以在目标元素的父元素上捕获到事件,实现事件委托和事件代理等功能。

        简单来说,捕获阶段是从父到子,冒泡阶段是从子到父,而实践开发中都是使用事件冒泡为主。

2.事件捕获

        从DOM的根元素开始去执行对应的事件,事件捕获需要写对应代码才能看到效果,语法如下:

DOM.addEventListener(事件类型,事件处理函数,是否使用捕获机制);

说明:

  • addEventListener第第三个参数传入true代表是捕获阶段触发(很少使用);
  • 若传入false代表冒泡阶段触发,默认就是false;
  • 若是用L0事件监听,则只有冒泡阶段,没有捕获。 

3.事件冒泡

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

举例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>事件冒泡</title>
    <style>
        .father{
            width: 50%;
            height: 300px;
            background-color: yellow;
        }
        .son{
            width: 50%;
            height: 300px;
            background-color: blue;
        }
    </style>
</head>
<body>
    我是爷爷元素
    <div class="father">
        我是父元素
        <div class="son">
            我是子元素
        </div>
    </div>
</body>
<script>
    const father = document.querySelector(".father");
    const son = document.querySelector(".son");
    document.addEventListener('click',()=>{
        alert("爷爷来了");
    });
    father.addEventListener('click',()=>{
        alert("爸爸来了");
    });
    son.addEventListener('click',()=>{
        alert("儿子来了");
    });
</script>
</html>

此时,若点击子元素,则父元素和爷元素的箭头函数也会被触发。

 

 

4.阻止事件冒泡

        因为默认就有冒泡模式的存在,所以很容易导致事件影响到父级元素,若想把事件就限制在当前元素内,就需要阻止事件冒泡。

语法:

事件对象.stopPropagation();

示例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>事件冒泡</title>
    <style>
        .father{
            width: 50%;
            height: 300px;
            background-color: yellow;
        }
        .son{
            width: 50%;
            height: 300px;
            background-color: blue;
        }
    </style>
</head>
<body>
    我是爷爷元素
    <div class="father">
        我是父元素
        <div class="son">
            我是子元素
        </div>
    </div>
</body>
<script>
    const father = document.querySelector(".father");
    const son = document.querySelector(".son");
    document.addEventListener('click',()=>{
        alert("爷爷来了");
    });
    father.addEventListener('click',(effervescence)=>{
        alert("爸爸来了");
        effervescence.stopPropagation();
    });
    son.addEventListener('click',(effervescence)=>{
        alert("儿子来了");
        effervescence.stopPropagation();
    });
</script>
</html>

 此方法可以阻断事件流动传播,不光在冒泡阶段有效,在捕获阶段同样有效。

5.阻止事件默认行为

        我们某些情况下需要阻止默认行为的发生,比如阻止链接的跳转,表单域的跳转。

语法:

事件对象.preventDefault();

示例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>阻止默认行为</title>
</head>
<body>
    <form action="#">
        <input type="submit" value="提交">
    </form>
</body>
<script>
    const form = document.querySelector('form');
    form.addEventListener("click",(e)=>{
        e.preventDefault();
    })
</script>
</html>

 6.解绑事件

(1)on事件方式

        直接使用null覆盖就可以实现事件的解绑。

语法:

btn.onclick = function(){
    alert("我被点击了");
}
btn.onclick = null;

(2)addEventListener方式

        必须使用removeEventListener(事件类型,事件处理函数[,获取捕获或者冒泡阶段])方法可以解绑事件,注意匿名函数无法被解绑。

function fn(){
    alert("我被点击了");
}
btn.addEventListener("click",fn);
btn.removeEventListener("click",fn);

二、一些注意事项和总结

1.鼠标经过事件

  • mouseover和mouseout会有冒泡效果;
  • mouseenter和mouseleave没有冒泡效果,这里推荐优先使用;

2.两种注册事件的区别

(1)传统on注册(L0)

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

(2)事件监听注册

  • 语法:addEventListener(事件类型,事件处理函数,是否使用捕获);
  • 后面注册事件不会覆盖前面注册的事件(同一个事件);
  • 可以通过第三个参数去确定在冒泡或者捕获阶段执行;
  • 必须使用removeEventLintener(事件类型,事件处理函数,是否使用捕获)解绑函数;
  • 匿名函数无法被解绑。
  • 34
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乔冠宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值