DOM事件进阶

1.什么是事件

事件(Event)是由 DOM 元素产生的资源,它可以由 JavaScript 代码操作。

在 Web 中,事件在浏览器窗口中被触发并且通常被绑定到窗口内部的特定部分 — 可能是一个元素、一系列元素、被加载到这个窗口的 HTML 代码或者是整个浏览器窗口。

例如:

  • 用户在某个元素上点击鼠标或悬停光标
  • 用户在键盘中按下某个按键
  • 用户调整浏览器的大小或者关闭浏览器窗口
  • 一个网页停止加载
  • 提交表单
  • 播放、暂停、关闭视频
  • 发生错误

下面看一个例子:页面中只有一个 button按钮,按下时,背景会变成随机的一种颜色

HTML部分:

<button>Change color</button>

JavaScript部分:

const btn = document.querySelector('button');

function random(number) {
  return Math.floor(Math.random()*(number+1));
}

btn.onclick = function() {  // L0的事件监听写法
  const randomColor = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
  document.body.style.backgroundColor = randomColor;
}

解释:使用 btn 变量存储 button元素,并使用了Document.querySelector() 函数。同时定义了一个返回随机数字的函数。代码第三部分就是事件处理器。btn变量指向 button 元素,在 button 这种对象上可触发一系列的事件,因此就可以使用事件处理器。我们通过将一个匿名函数(这个赋值函数包括生成随机色并赋值给背景色的代码)赋值给“点击”事件处理器参数,监听“点击”这个事件。从而只要点击事件在<button>元素上触发,该段代码就会被执行。即每当用户点击它时,都会运行此段代码。

2.事件流

概念:事件完整执行过程中的流动路径(包含捕获和冒泡)

2.1 事件对象

在事件处理函数内部,可能会出现一个固定指定名称的参数,例如eventevt或简单的e。这被称为事件对象,它被自动传递给事件处理函数,以提供额外的功能和信息。

例如:

function bgChange(e) {
  const randomColor = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
  e.target.style.backgroundColor = randomColor ;
  console.log(e);
}

btn.addEventListener('click', bgChange);

解释:在上面的函数中包括一个事件对象e,并在函数中设置背景颜色样式在 e.target 上,事件对象 e 的 target 属性始终是事件刚刚发生的元素的引用。所以在这个例子中,我们在按钮上设置一个随机的背景颜色。

2.2 事件捕获

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

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

(其中第三个参数值为true或者false,默认为false代表冒泡阶段触发,true则代表是捕获阶段触发。)

2.3 事件冒泡

概念:当一个元素事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发,这个过程被称为事件冒泡。

简单理解:当一个元素触发事件时,会依次向上调用所有的父级元素的同名事件。

(注意:事件冒泡是默认存在的。)

例如:

HTML部分:

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

CSS部分:

  .father {
      width: 500px;
      height: 500px;
      background-color: pink;
    }

    .son {
      width: 200px;
      height: 200px;
      background-color: purple;
    }

JavaScript部分:

 const fa = document.querySelector('.father')
    const son = document.querySelector('.son')

    document.addEventListener('click', function () {
      alert('我是爷爷')
    })
    fa.addEventListener('click', function () {
      alert('我是爸爸')
    })
    son.addEventListener('click', function () {
      alert('我是儿子')
    })

解释,创建了两个div标签,依次监听事件并进行事件冒泡。当点击紫色div标签时,会从类名为son的事件的alert语句开始向上依次执行,从而依次显示:我是儿子,我是爸爸,我是爷爷。而点击粉色的div标签时,会从类名为father的alert语句依次向上执行,从而显示:我是爸爸,我是爷爷。

2.4 阻止冒泡

1.为什么要阻止冒泡

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

2.语法

          事件对象.stopPropagation();

注意:上述语法阻止的是流动传播,所以事件的捕获和冒泡都可以阻止。

例如:

 const fa = document.querySelector('.father')
    const son = document.querySelector('.son')

    document.addEventListener('click', function () {
      alert('我是爷爷')
    })
    fa.addEventListener('click', function () {
      alert('我是爸爸')
    })
    son.addEventListener('click', function (e) {
      alert('我是儿子')
      // 阻止流动传播  事件对象.stopPropagation()
      e.stopPropagation()
    })

将事件冒泡的JavaScript部分给son的事件监听内加个事件对象e和函数e.stopPropagation(),就可以让son的事件不在向上执行,只执行“我是儿子”的输出。

2.5 事件委托

冒泡允许利用事件委托——这个概念依赖于这样一个事实,如果你想要在大量子元素中单击任何一个都可以运行一段代码,您可以将事件监听器设置在其父节点上,并让子节点上发生的事件冒泡到父节点上,而不是每个子节点单独设置事件监听器。

一个很好的例子是一系列列表项,如果你想让每个列表项被点击时弹出一条信息,您可以将click单击事件监听器设置在父元素<ul>上,这样事件就会从列表项冒泡到其父元素<ul>上。

例如:

HTML部分:

<ul>
        <li>第1个孩子</li>
        <li>第2个孩子</li>
        <li>第3个孩子</li>
        <li>第4个孩子</li>
        <li>第5个孩子</li>
        <P>我不需要变色</P>
    </ul>

JavaScript部分:

// 点击每个小li 当前li文字变为红色
        // 按照事件委托方式
        //  1.获得父元素
        const ul = document.querySelector('ul')
        ul.addEventListener('click',function(e){
            // alert('11')
            // this.style.color = 'red'
            // e.target.style.color = 'red'
            // console.dir(e.target)
            if (e.target.tagName === 'LI'){
                e.target.style.color = 'red'
            }
        })

 3.结论:

事件并不是 JavaScript 的核心部分——它们是在浏览器 Web APIs 中定义的。理解 JavaScript 在不同环境下使用不同的事件模型十分重要。所以让我们一起学习,一起进步。谢谢大家的观看。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值