JavaScript 中的事件模型,理解什么是事件捕获与冒泡、事件目标、事件委托、事件对象、事件处理程序、事件传播与组织

😉 你好呀,我是爱编程的Sherry,很高兴在这里遇见你!我是一名拥有十多年开发经验的前端工程师。这一路走来,面对困难时也曾感到迷茫,凭借不懈的努力和坚持,重新找到了前进的方向。我的人生格言是——认准方向,坚持不懈,你终将迎来辉煌!欢迎关注我😁,我将在这里分享工作中积累的经验和心得,希望我的分享能够给你带来帮助。
🎯如果你有任何困惑或疑问欢迎评论区给我留言哦,我收到后会第一时间为你答疑解惑😉

引言

JavaScript 中的事件模型是浏览器如何处理用户交互(如点击、键盘输入、鼠标移动等)或其他事件(如加载完成、定时器等)的机制。理解事件模型有助于我们处理这些事件并响应它们。JavaScript 的事件模型主要包括以下几个部分:

1. 事件流(Event Flow)

事件流是指事件在 DOM(文档对象模型)树中传播的过程。HTML 页面由 DOM 树表示,事件可以沿着 DOM 树的路径传播。事件流由三个阶段组成:

阶段 1:事件捕获阶段(Capturing Phase)

事件从最外层的元素(通常是 windowdocument)向下传播,依次经过各个子元素,直到事件目标元素。

阶段 2:目标阶段(Target Phase)

事件到达事件目标元素,即用户交互的具体元素。

阶段 3:事件冒泡阶段(Bubbling Phase)

事件从目标元素开始向上传播,依次经过其祖先元素,直到最外层的元素。

2. 事件冒泡(Event Bubbling)

事件冒泡是指事件首先在目标元素上触发,然后逐级向上传播到祖先元素,直到 window。这种机制允许我们在父级元素上监听子级元素的事件,因为事件最终会冒泡到父级元素。

举个栗子:
<div id="parent">
  <button id="child">Click me</button>
</div>

<script>
  document.getElementById('parent').addEventListener('click', function() {
    console.log('Parent clicked');
  });

  document.getElementById('child').addEventListener('click', function() {
    console.log('Child clicked');
  });
</script>

输出顺序:

Child clicked
Parent clicked

当点击按钮时,事件先在按钮上触发,然后冒泡到 div 父级元素上。

3. 事件捕获(Event Capturing)

与事件冒泡相反,事件捕获是事件从根元素向目标元素传播的过程。默认情况下,事件处理程序只会在冒泡阶段执行,但我们可以指定事件在捕获阶段执行。

举个栗子:
<div id="parent">
  <button id="child">Click me</button>
</div>

<script>
  document.getElementById('parent').addEventListener('click', function() {
    console.log('Parent clicked');
  }, true); // 使用 true 表示捕获阶段

  document.getElementById('child').addEventListener('click', function() {
    console.log('Child clicked');
  });
</script>

输出顺序:

Parent clicked
Child clicked

在这个例子中,由于我们在 parent 的事件监听中使用了 trueparent 的点击事件首先在捕获阶段触发。

4. 事件委托(Event Delegation)

事件委托是利用事件冒泡机制,将事件监听器绑定到父级元素,而不是直接绑定在每个子元素上。这有助于减少内存消耗,特别是在动态生成的元素或大量子元素的情况下。

举个栗子:
<ul id="list">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>

<script>
  document.getElementById('list').addEventListener('click', function(event) {
    if (event.target.tagName === 'LI') {
      console.log(event.target.innerText + ' clicked');
    }
  });
</script>

在这个例子中,我们将点击事件绑定到 ul 元素,而不是每个 li 元素。通过 event.target 判断具体点击的元素是哪一个子节点。

5. 事件对象(Event Object)

当事件触发时,浏览器会创建一个事件对象,并将其作为参数传递给事件处理函数。这个事件对象包含了有关事件的信息,包括事件类型、事件目标、鼠标位置、键盘按键等。

常用的属性和方法:

event.type:

事件的类型(如 'click''keydown')。

event.target:

触发事件的元素。

event.currentTarget:

绑定事件处理程序的元素。

event.stopPropagation():

阻止事件继续冒泡或捕获。

event.preventDefault():

阻止事件的默认行为(如阻止链接跳转、表单提交等)。

event.clientX / event.clientY:

鼠标点击的横纵坐标。

举个栗子:
document.getElementById('child').addEventListener('click', function(event) {
  console.log('Event type: ', event.type);        // 输出: 'click'
  console.log('Target: ', event.target);          // 输出: 触发点击的元素
  console.log('Mouse position: ', event.clientX, event.clientY); // 输出: 鼠标点击位置
});

6. 事件处理程序(Event Handlers)

事件处理程序是用户定义的函数,用于响应某个事件。事件处理程序可以通过三种方式添加到元素上:

HTML 属性方式
<button onclick="handleClick()">Click me</button>

<script>
  function handleClick() {
    console.log('Button clicked');
  }
</script>
addEventListener 方法(推荐方式):
document.getElementById('button').addEventListener('click', function() {
  console.log('Button clicked');
});
on 前缀属性(不推荐使用,可能会覆盖其他处理程序):
document.getElementById('button').onclick = function() {
  console.log('Button clicked');
};

7. 事件传播与阻止

在 JavaScript 中,事件传播过程中可以通过两种方法来控制事件的传播:

event.stopPropagation()

阻止事件进一步传播(无论是冒泡还是捕获阶段)。常用于避免事件冒泡到父级元素中。

document.getElementById('child').addEventListener('click', function(event) {
  event.stopPropagation(); // 阻止事件冒泡
  console.log('Child clicked');
});
event.preventDefault()

阻止事件的默认行为,如表单提交、链接跳转等。

document.getElementById('link').addEventListener('click', function(event) {
  event.preventDefault(); // 阻止链接跳转
  console.log('Link clicked but default action prevented');
});

8. 事件模型的使用场景

表单验证

使用 event.preventDefault() 阻止表单的默认提交行为,执行自定义验证逻辑。

动态 UI 元素

通过事件委托处理动态生成的子元素的事件(如列表项的删除、点击事件)。

交互式用户体验

通过事件冒泡和捕获机制,处理用户点击、悬停、拖动等交互事件。

总结

事件流

事件从最外层元素向内传播(捕获阶段),然后再从内层向外传播(冒泡阶段)。

事件捕获事件冒泡

分别控制事件传播的顺序,默认事件处理在冒泡阶段执行。

事件委托

是利用事件冒泡,将事件监听器绑定到父级元素,处理子元素的事件。

事件对象

提供了有关事件的信息,可以通过 event.target 访问具体的目标元素,使用 stopPropagationpreventDefault 控制事件传播和默认行为。

JavaScript 的事件模型让开发者能够方便地处理各种用户交互,提升网页的动态性和响应能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Sherry Tian

打赏1元鼓励作者

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

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

打赏作者

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

抵扣说明:

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

余额充值