关于本文
本文是通过利用生成式 AI 的自动生成流程创建的。通过使用虚拟数据和浏览器操作,学习 Tone.js 的用途、机制以及失败时的观察要点。不会访问实际的服务或个人信息。验证状态:我们于 2026-10-30 将官方资料与 GitHub 固定提交的 HTML/JavaScript 进行了核对。未执行实际浏览器操作、CDN 获取及渲染/音频输出,文中的结果为代码的预期值。
| 项目 | 内容 |
|---|---|
| 对象 | Chrome/Edge/Firefox 等现代浏览器(未验证真机兼容性) |
| 使用库 | Tone.js(教材内版本: 15.1.22) |
| 费用 | 演示源码本身不需要付费 API。通信费用和使用条件取决于环境 |
| 数据 | 页面内的虚拟数据。无需认证信息、位置信息及企业数据 |
| 学习操作 | 播放四音旋律并更改节拍 |
为什么要尝试这项技术
JavaScript 不仅可以改变屏幕的颜色和位置,还可以制作声音。Tone.js 是一个使 Web Audio API 更易于使用的库。这次我们将播放 C、E、G 和高音 C 这四个音符。它的特点不是播放乐器的录音文件,而是在浏览器中合成音效,并以时间差进行播放。即使屏幕没有变化,结果也能通过耳朵感知,因此这是一个很容易让人体会到事件与时间编程乐趣的题材。为了防止音量突然变大,演示的初始状态设置为静音,并提醒用户注意音量设置。
在制作动态示例时,不能止步于“看到它动了”这一表面事实,而必须区分“哪个输入改变了哪个变量,哪段处理更新了渲染”。本教程将在屏幕上明确显示这种变化。在将其引入实际服务时,请另外设计认证和存储处理。
首先尝试:在线演示与预期结果
将浏览器的扬声器音量调低,然后点击“播放4个音符”。如果成功,预计会听到四个声音,且状态变为已预订。接着将 BPM 从 100 降到 60,确认音符之间的间隔是否变长。BPM 是 Beats Per Minute 的缩写,表示每分钟的拍数。如果将其提高到 180,间隔就会变短。如果不发声,请排查浏览器的权限、设备的静音状态以及其他标签页的音频输出目标。在音频实验中,不能仅凭屏幕上的 SUCCESS 显示就认定听觉上的执行已成功。
操作前需确认的事项
确认您的电脑可以运行 JavaScript。不需要管理员权限。
打开浏览器的开发者工具,准备检查控制台(Console)中是否有错误,以及网络面板(Network)中是否有 CDN 获取失败的情况。
如果演示实际上未公开,请将 Daily Code 侧的
index.html和app.js保存到同一个文件夹中,并通过本地 HTTP 服务器打开。如果使用模块(module),不保证通过 file:// 直接运行能够正常工作。比较操作前后的结果。如果与期望值不同,请先记录“什么没有显示出来”。
机制全景图
flowchart LR
A["入力やクリック"] --> B["イベントを受ける"]
B --> C["Tone.js のAPI"]
C --> D["状態と描画を更新"]
D --> E["見た目と文字で確認"]
此图是用于学习的概念图,并未展示浏览器内部实现或网络通信的细节。不过,无论什么库,“操作如何传达至哪个变量”这一追踪过程都是相通的。
无法使用公开演示时的本地确认
固定提交的HTML 主体和JavaScript 主体从 GitHub 的 Raw 视图中分别index.html和app.js作为相同的新文件夹保存。仅靠 README 无法运行。在 Windows 上,在该文件夹中打开 PowerShell,并在py -3 -m http.server 8000 --bind 127.0.0.1,在 Linux/macOS 上执行python3 -m http.server 8000 --bind 127.0.0.1,然后打开同一台电脑的http://127.0.0.1:8000/。若要退出,请在终端中输入Ctrl+C。由于浏览器会从外部 CDN 获取库本身,如果无法连接,请检查控制台(Console)和网络(Network)的错误。此步骤仅为复现指南,并非本文的浏览器实际测量报告。
工作原理:解读 API
浏览器限制了在用户未进行操作的阶段播放声音。Tone.start() 必须与点击等用户操作相结合来调用。音源由 Tone.Synth 创建,并通过 toDestination 连接到扬声器的输出路径。使用 triggerAttackRelease 指定音符名称、长度和开始时间。与使用 JavaScript 的 setTimeout 逐个播放音效的方式相比,利用 AudioContext 的时间来预定演奏更容易设计音符的时机。
如何阅读最简代码
await Tone.start(); // クリックのイベント内で呼ぶ
const synth = new Tone.Synth({volume: -18}).toDestination();
synth.triggerAttackRelease("C4", "8n", Tone.now());
以上是提取了 API 要点的摘录。它并非可以直接复制并独立运行的完整文件。用于运行的 HTML 和实现代码全集请在 Daily Code 侧的 README / 演示文件中确认。追踪哪个函数选择了 HTML 元素、哪一行更新了数值,并使用已知的虚构值进行尝试。
仅修改一个条件进行比较
将音符序列从 C4、E4、G4、C5 更改为 C4、F4、G4、B4 会改变音效。虽然也可以用数字来写频率,但一开始使用音名会更容易阅读。更改音符长度时,可能会与相邻的音符重叠。因此,播放预定的时间间隔与单个音符的长度应分开考虑。如果要扩展为连续播放,则在停止、重新开始和更改速度时对已预定音符的处理将变得非常重要。
比较的步骤是:记录初始值,只修改一个地方,然后确认结果是否出现在预期的部位。如果一次修改多个输入,就会分不清是什么产生了影响。请连同恢复到修改前状态的操作一起进行验证。
失败时应该检查哪里
多次按下播放按钮会导致声音重叠。本示例基本上会重复使用音源,而不是每次都持续创建新的乐器。停止时会进行 dispose 并清理善后,但与已预定音符的关系需要通过实际浏览器进行额外确认。如果在活动会场公开发布,重要的是不要自动播放、随时提供停止声音的操作,并并记考虑到听觉的替代视觉信息。
| 观察到的状态 | 排查的点 | 应对示例 |
|---|---|---|
| 画面保持初始状态不变 | 脚本获取、初始化与事件注册 | 检查 Console / Network / script 标签 |
| 显示内容改变,但含义不对 | 输入值、数组、单位与更新目标 | 固定数值,逐个条件进行检查 |
| 无法点击按钮 | 选择器与 DOM 生成顺序 | 检查 HTML 以确认 id 是否一致 |
| 仅部分终端无法运行 | 浏览器功能、权限、CDN 与性能 | 记录终端、版本以及复现操作 |
浏览器内部的错误与公开 Web 服务器的故障有所不同。前者通过开发者工具中的错误内容排查,后者通过 HTTP 响应或资产分发条件排查。切勿将未知的失败表述为成功,这是提升技术备忘录可靠性的关键。
在业务与学习中的应用
可应用于打字教材的反馈、游戏音效、时机学习以及音高可视化等。但是,提示音的播放取决于终端状态,不可仅依赖声音来发出重要警告。在业务系统中,需要结合屏幕文本、通知历史和声音来进行设计。
引入前需确定的事项
向读者公开时,需确定显示的数据来源、谁拥有修改权限、保留在屏幕上的信息种类,以及更新库时的检查项目。本次演示中既没有登录功能,也没有服务器保存功能。因此,在添加运营功能之前,建议首先区分“按预期显示的最小部分”以及“需要实务可靠性、权限和备份的部分”。由于第三方 CDN 涉及外部通信,因此必须提前确认企业网络是否允许使用。
与其他方式进行比较
| 方式 | 适用场景 | 注意事项 |
|---|---|---|
| Tone.js | 适合播放4音符旋律并更改速度等符合目的的场景 | 需要更新依赖库并管理使用条件 |
| 浏览器标准API | 自行开发小型功能 | 自行确认规范和兼容性 |
| 静态图像和表格 | 无需操作的说明 | 无法当场体验状态的变化 |
库是按需选择的工具。请结合想达到的目标和学习成本进行权衡。在小规模页面中,不把“引入库”作为目标会更容易维护。
GitHub 示例
博客正文侧重背景与思路,Daily Code侧重用于运行和改造的代码,两者职责分明。不包含用于向外部服务发布或保存的API。
官方信息与一手资料
资料确认范围:截至2026-10-27编辑时参考了官方文档。不保证链接的未来变更以及所有的CDN资产响应。
验证范围的补充
核对了保存在GitHub上的固定源码与官方API说明。尚未验证浏览器操作、CDN加载以及在各操作系统上的结果。在实际确认运行时,请检查控制台(Console)与网络(Network),切勿仅凭画面的SUCCESS显示就断定所有条件均已成功。
