让你的网站说话(不吓到用户)
发布: (2026年2月6日 GMT+8 15:30)
4 min read
原文: Dev.to
Source: Dev.to

介绍
说实话:大多数网站太安静了。我们把一生都花在盯着发光的矩形屏幕上,像1995年那样阅读文字。但你的浏览器拥有一种叫 Web Speech API 的隐藏超能力。它可以说话。而且,我不是指那些2008年奇怪的自动播放视频广告。

今天,我们要构建一个天气仪表盘,它不仅显示温度——还能概括天气氛围并朗读给你听。
The Stack
- React.js – 用于组件和状态管理。
- Web Speech API – 特别是
window.speechSynthesis。 - OpenWeatherMap API – 用于天气数据(或您选择的任何天气 API)。
1. “大脑”:获取与摘要
首先,我们需要一些有价值的话。像 {"temp": 273.15} 这样的原始 JSON 响应对机器来说很棒,但人类更喜欢“太冷了,待在室内”。
const fetchWeatherSummary = async (city) => {
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=YOUR_API_KEY&units=metric`
);
const data = await response.json();
// A simple summarizer (you could pipe this to an LLM for more “flavour”)
return `Currently in ${data.name}, it's ${data.main.temp} degrees with ${data.weather[0].description}. My professional advice? ${data.main.temp > 25 ? "Wear a hat." : "Grab a jacket."}`;
};
2. “语音”:认识 SpeechSynthesis
window.speechSynthesis 控制器管理着“utterances”(即你想要说的话)的队列。
useSpeech 钩子
将语音引擎封装在一个简洁的 React 钩子中,以保持 UI 逻辑整洁。
import { useState, useEffect } from 'react';
export const useSpeech = () => {
const [voices, setVoices] = useState([]);
useEffect(() => {
const updateVoices = () => setVoices(window.speechSynthesis.getVoices());
window.speechSynthesis.onvoiceschanged = updateVoices;
updateVoices();
}, []);
const speak = (text: string, voiceName?: string, rate = 1, pitch = 1) => {
// Cancel any ongoing chatter
window.speechSynthesis.cancel();
const utterance = new SpeechSynthesisUtterance(text);
// Choose voice or fall back to default
if (voiceName) {
utterance.voice = voices.find(v => v.name === voiceName) || null;
}
utterance.rate = rate; // 0.1 to 10
utterance.pitch = pitch; // 0 to 2
window.speechSynthesis.speak(utterance);
};
return {
speak,
voices,
pause: () => window.speechSynthesis.pause(),
resume: () => window.speechSynthesis.resume(),
};
};
Dashboard 组件
将所有内容粘合在一起,并使用一个按钮来获取数据并朗读出来。
import React, { useState } from 'react';
import { useSpeech } from './hooks/useSpeech';
const WeatherDashboard = () => {
const [summary, setSummary] = useState("");
const { speak, voices } = useSpeech();
const handleWeatherUpdate = async () => {
const text = await fetchWeatherSummary("London");
setSummary(text);
speak(text, voices[0]?.name, 1.1, 1);
};
return (
<div>
<h2>Weather Talker</h2>
<button onClick={handleWeatherUpdate}>Get Audio Summary</button>
{summary && (
<p>"{summary}"</p>
)}
</div>
);
};
export default WeatherDashboard;
Speech API 的专业技巧
- 语音是惰性的 – 它们并不总是立即加载。钩子中的
onvoiceschanged事件确保voices数组已填充。 - 需要用户激活 – 浏览器会阻止未由用户手势触发的音频。请在点击处理函数或类似事件中调用
speak()。 - 快捷库 – NPM 包 vocalize.ts 为该 API 提供了 TypeScript 优先的封装。目前维护较少,但核心逻辑运行良好。
为什么要这么做?
可访问性是显而易见的答案。屏幕阅读器很棒,但特定的“为我朗读”功能可以帮助多任务用户或视力受限者。
让你的电脑回应你也很有趣。但除非你已经做好心理准备,否则不要给它一个讽刺的个性。
祝编码愉快!