菜单

事件与事件处理

相关源文件

本文档详细介绍了 Svelte 的事件处理系统,解释了事件如何附加到 DOM 元素、事件委托如何工作以及 Svelte 的事件系统如何与响应式系统集成。有关组件事件和自定义事件创建的信息,请参阅组件通信

概述

Svelte 通过 on: 指令提供了一种声明式的方式来处理 DOM 事件。在后台,Svelte 实现了一个高效的事件系统,该系统支持事件委托、捕获阶段处理和被动事件,同时确保与 Svelte 的响应式系统的正确集成。

来源

事件类型

Svelte 支持所有标准的 DOM 事件。事件处理程序使用针对不同事件类别的专用事件处理程序类型进行类型化。

支持的事件类别

事件类别描述处理程序类型
剪贴板事件复制、剪切、粘贴ClipboardEventHandler
组合事件用于 IME 输入CompositionEventHandler
焦点事件焦点、模糊等FocusEventHandler
表单事件提交、更改等FormEventHandler
键盘事件KeyDown、KeyUp、KeyPressKeyboardEventHandler
鼠标事件点击、悬停等MouseEventHandler
触摸事件TouchStart、TouchMove 等TouchEventHandler
指针事件现代指针设备事件PointerEventHandler
UI 事件滚动、调整大小UIEventHandler
滚轮事件鼠标滚轮WheelEventHandler
动画事件动画开始/结束AnimationEventHandler
过渡事件CSS 过渡TransitionEventHandler
媒体事件音频/视频播放EventHandler
拖拽事件拖放操作DragEventHandler

来源

基本事件处理

在 Svelte 中,使用 on: 指令后跟事件名称来将事件添加到元素。

事件处理程序可以是

  • 函数引用(如上所示)
  • 内联函数表达式
  • 一个调用语句(事件触发时执行)

事件对象

事件处理程序接收标准的 DOM 事件对象作为参数,其类型根据正在处理的事件而定。

来源

事件修饰符

Svelte 提供了事件处理的特殊修饰符,用于控制事件行为,无需额外的 JavaScript 代码。

修饰符类型

修饰符描述
capture在捕获阶段而不是冒泡阶段触发处理程序
once第一次运行后移除处理程序
passive通过触摸/滚轮事件提高滚动性能(从不调用 preventDefault()
nonpassive显式将 passive 设置为 false
preventDefault在运行处理程序之前调用 event.preventDefault()
stopPropagation在运行处理程序之前调用 event.stopPropagation()
stopImmediatePropagation在运行处理程序之前调用 event.stopImmediatePropagation()
self仅当 event.target 是元素本身时才触发处理程序
trusted仅当 event.isTrusted 为 true 时才触发处理程序

修饰符可以链式调用

可以使用 on:eventname:capture 语法来指定捕获阶段的事件监听器。

来源

事件架构

Svelte 的事件系统区分两种类型的事件处理实现:

  1. 委托事件 - 为了提高效率,常见的事件是通过事件委托实现的。
  2. 直接事件 - 一些事件直接附加到元素上。

事件流图

来源

事件委托实现

事件委托是一种技术,它将单个事件监听器附加到父元素,而不是附加到多个子元素上。当事件发生时,系统会确定哪个子元素是目标,并执行相应的处理程序。

在 Svelte 中,委托事件处理程序直接存储在具有 __eventName 形式的属性的元素上。

委托系统

  1. 注册应被委托的事件类型
  2. 在文档级别附加一个事件监听器以处理这些事件
  3. 当事件发生时,从目标元素向上遍历 DOM 树以查找处理程序
  4. 以正确的 this 上下文和当前目标执行处理程序

来源

事件创建

create_event 函数负责将事件处理程序附加到 DOM 元素。

对于指针事件、触摸事件和滚轮事件,事件附加是通过微任务延迟的,以处理一个 Chrome 错误,该错误导致这些事件在克隆的 DOM 元素上无法正常工作。

来源

与响应式的集成

事件处理程序在 Svelte 的响应式上下文之外运行,以防止意外的副作用。 without_reactive_context 函数在执行事件处理程序之前会临时挂起当前响应和效果。

这确保了

  1. 事件处理程序中的状态更改不会导致意外的响应运行。
  2. 事件流不会被响应式更新中断。
  3. 同步的 blur 事件不会在当前活动的响应中运行。

来源

事件绑定类型

Svelte 支持多种事件绑定方式。

  1. 标准事件绑定 - 使用 on:event={handler}
  2. 组件事件转发 - 使用 on:event 将事件转发给父组件。
  3. 带水合的 DOM 事件绑定 - 在服务器端渲染和水合过程中处理事件。

标准事件绑定

最常见的形式是将 DOM 事件绑定到处理程序函数。

这会被编译成调用 Svelte 的内部事件系统,该系统会创建并附加适当的事件监听器。

水合期间的事件绑定

对于带有水合的服务器端渲染,Svelte 支持捕获在水合完成之前发生的事件,并在水合完成后重放它们。

来源

事件验证和开发警告

在开发模式下,Svelte 会验证事件处理程序,以帮助捕获常见的错误。

常见的事件处理程序错误

  1. 非函数处理程序 - 当处理程序不是函数时(例如,直接值)。
  2. 自执行函数 - 当处理程序有一个会立即执行它的尾部 () 时。

apply 函数会检查这些问题并提供有用的警告。

来源

事件绑定与表单

Svelte 为表单元素提供了特殊处理,将事件处理与表单功能集成。

在表单元素中绑定事件

对于输入、选择和文本区域等表单元素,事件处理通常与值绑定相关。

listen_to_event_and_reset_event 函数用于:

  1. 监听主要事件(例如,“input”)
  2. 为表单重置事件设置处理程序
  3. 相应地更新绑定

来源

特殊元素的事件处理

某些元素具有特殊的事件处理要求。

媒体元素事件

音频和视频元素对 currentTime、volume 和播放状态等属性具有专门的事件处理。

对于像 currentTime 这样连续变化的属性,Svelte 会将 requestAnimationFrame 循环与标准的 timeupdate 事件结合,以实现平滑的更新。

来源

窗口和文档事件

Svelte 通过 <svelte:window><svelte:document> 元素提供了窗口和文档事件的特殊处理。

窗口和文档绑定处理全局级别的事件,例如滚动、调整大小和焦点更改。

来源

结论

Svelte 的事件处理系统提供了一种声明式且类型安全的方式来管理 DOM 事件,同时通过与框架的响应式系统无缝集成。该实现通过事件委托平衡了性能,并通过清晰的语法和有用的警告提供了开发者便利性。

该系统的主要优势包括:

  1. 全面支持所有 DOM 事件类型,并提供正确的 TypeScript 类型
  2. 通过事件委托实现性能优化
  3. 与 Svelte 的响应式系统无缝集成
  4. 对不同元素类型及其独特事件进行特殊处理
  5. 支持事件修饰符,减少样板代码
  6. 在 SSR 和水合过程中表现稳健

通过其事件系统,Svelte 使 DOM 交互既易于编写又高效执行。