<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>JavaScript on 映屿</title>
    <link>https://blog.verdant.ee/tags/javascript/</link>
    <description>Recent content in JavaScript on 映屿</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    
      <managingEditor>i@glowisle.me (五葉地錦)</managingEditor>
    
    
      <webMaster>i@glowisle.me (五葉地錦)</webMaster>
    
    
    
    <lastBuildDate>Fri, 04 Jul 2025 10:46:53 +0000</lastBuildDate>
    
    
    <atom:link href="http://blog.verdant.ee/tags/javascript/atom.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>使用Javascript TSS和Highlights构建一个文本阅读器</title>
      <link>https://blog.verdant.ee/posts/%E7%94%A8javascript-tss%E5%92%8Chighlights%E6%9E%84%E5%BB%BA%E4%B8%80%E4%B8%AA%E5%8F%A5%E7%BA%A7%E6%96%87%E6%9C%AC%E9%98%85%E8%AF%BB%E5%99%A8/</link>
      <pubDate>Fri, 04 Jul 2025 10:46:53 +0000</pubDate><author>i@glowisle.me (五葉地錦)</author>
      <guid>https://blog.verdant.ee/posts/%E7%94%A8javascript-tss%E5%92%8Chighlights%E6%9E%84%E5%BB%BA%E4%B8%80%E4%B8%AA%E5%8F%A5%E7%BA%A7%E6%96%87%E6%9C%AC%E9%98%85%E8%AF%BB%E5%99%A8/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;原文：https://jsdev.space/tts-sentence-reader/&lt;/p&gt;&#xA;&lt;p&gt;翻译：Verdant&lt;a href=&#34;mailto:i@glowisle.me&#34;&gt;i@glowisle.me&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;figure class=&#34;image-caption&#34;&gt;&#xA;    &lt;img src=&#34;https://jsdev.space/.netlify/images?url=_astro%2Ftts-sentence-reader.hV9whx3I.png&amp;amp;w=800&amp;amp;h=800&#34; alt=&#34;&#34;&gt;&#xA;    &lt;figcaption&gt;&lt;/figcaption&gt;&#xA;&lt;/figure&gt;&lt;/p&gt;&#xA;&lt;p&gt;在这篇文章中，我们将构建一个简单的Web工具来探究&lt;strong&gt;Text-toSpeech(TTS)&lt;strong&gt;在JavaScript中是如何工作的。我们也将深入研究&lt;/strong&gt;句子级高亮&lt;/strong&gt;的工作逻辑。这两项功能经常结合在一起使用，以走到浏览器中打造无障碍的动态阅读体验。&lt;/p&gt;&#xA;&lt;p&gt;步骤:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;学习在浏览器中,TTS是如何工作的&lt;/li&gt;&#xA;&lt;li&gt;探究动态高亮句子的实现方法&lt;/li&gt;&#xA;&lt;li&gt;用HTML, CSS, JavaScript构建一个小工具(&lt;a href=&#34;https://codepen.io/jsdevspace/pen/YPXRRjO&#34;&gt;Demo &amp;amp; Code&lt;/a&gt;)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;-浏览器中的tts概述&#34;&gt;📢 浏览器中的TTS概述&lt;/h2&gt;&#xA;&lt;p&gt;JavaScript提供一个内置的API：&lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis&#34;&gt;&lt;code&gt;SpeechSynthesis&lt;/code&gt;&lt;/a&gt;，它允许我们使用系统中的可用嗓音去大声朗读问文字。&lt;/p&gt;&#xA;&lt;h3 id=&#34;核心对象&#34;&gt;核心对象:&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;speechSynthesis&lt;/code&gt; — 控制播放、暂停、恢复、停止&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;SpeechSynthesisUtterance&lt;/code&gt; — 作为TTS引擎的待播报文本&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;示例&#34;&gt;✨示例:&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d6cbb4;background-color:#252b2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; msg &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;new&lt;/span&gt; SpeechSynthesisUtterance(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;Hello, world!&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d699b6&#34;&gt;window&lt;/span&gt;.speechSynthesis.speak(msg);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;-添加嗓音和配置&#34;&gt;⚙️ 添加嗓音和配置&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d6cbb4;background-color:#252b2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; utter &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;new&lt;/span&gt; SpeechSynthesisUtterance(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;This is a test&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; voices &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;window&lt;/span&gt;.speechSynthesis.getVoices();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;utter.voice &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; voices.find(v =&amp;gt; v.lang &lt;span style=&#34;color:#7a8478&#34;&gt;===&lt;/span&gt; &lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;en-US&amp;#39;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;utter.rate &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;1.2&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;utter.pitch &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;1&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d699b6&#34;&gt;window&lt;/span&gt;.speechSynthesis.speak(utter);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;你也可以追踪朗读的开始和结束：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d6cbb4;background-color:#252b2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;utter.onstart &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; () =&amp;gt; console.log(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;Started speaking&amp;#39;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;utter.onend &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; () =&amp;gt; console.log(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;Finished speaking&amp;#39;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;-句子高亮&#34;&gt;✍️ 句子高亮&lt;/h2&gt;&#xA;&lt;p&gt;展示给用户哪一个句子正在阅读，我们需要用CSS和JavaScript来高亮文本。&lt;/p&gt;&#xA;&lt;h3 id=&#34;示例-html&#34;&gt;示例 HTML:&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d6cbb4;background-color:#252b2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;p&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;sentence&amp;#34;&lt;/span&gt;&amp;gt;First sentence.&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;span&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;sentence&amp;#34;&lt;/span&gt;&amp;gt;Second sentence.&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;span&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;p&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;处理高亮的css&#34;&gt;处理高亮的CSS:&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d6cbb4;background-color:#252b2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.sentence.active {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;background-color&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;yellow&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;font-weight&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;bold&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;javascript高亮逻辑&#34;&gt;JavaScript高亮逻辑：&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d6cbb4;background-color:#252b2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;function&lt;/span&gt; highlight(index) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#d699b6&#34;&gt;document&lt;/span&gt;.querySelectorAll(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;.sentence&amp;#39;&lt;/span&gt;).forEach((el, i) =&amp;gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    el.classList.toggle(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;active&amp;#39;&lt;/span&gt;, i &lt;span style=&#34;color:#7a8478&#34;&gt;===&lt;/span&gt; index);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  });&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;项目-使用tss和高亮的阅读器&#34;&gt;🚀项目: 使用TSS和高亮的阅读器&lt;/h1&gt;&#xA;&lt;p&gt;我们的程序将要：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;逐句朗读文本&lt;/li&gt;&#xA;&lt;li&gt;高亮朗读中的文本&lt;/li&gt;&#xA;&lt;li&gt;提供播放、暂停、恢复、停止&lt;/li&gt;&#xA;&lt;li&gt;让用户能选择嗓音&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;-html结构&#34;&gt;📄 HTML结构&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d6cbb4;background-color:#252b2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;html&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;lang&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;en&amp;#34;&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;head&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;meta&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;charset&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;UTF-8&amp;#34;&lt;/span&gt; /&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;meta&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;viewport&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;content&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;width=device-width, initial-scale=1.0&amp;#34;&lt;/span&gt; /&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;meta&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;content&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;Build an interactive sentence-level text-to-speech reader with highlight, playback controls, and local progress tracking using HTML and JavaScript.&amp;#34;&lt;/span&gt; /&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;title&lt;/span&gt;&amp;gt;Interactive TTS Article Reader&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;title&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;head&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;body&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;h1&lt;/span&gt;&amp;gt;Read Along TTS Demo&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;h1&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;toolbar&amp;#34;&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;button&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;start&amp;#34;&lt;/span&gt;&amp;gt;Play&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;button&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;button&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;pause&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;disabled&lt;/span&gt;&amp;gt;Pause&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;button&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;button&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;resume&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;disabled&lt;/span&gt;&amp;gt;Resume&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;button&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;button&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;stop&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;disabled&lt;/span&gt;&amp;gt;Stop&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;button&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;button&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;reset&amp;#34;&lt;/span&gt;&amp;gt;Reset&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;button&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;voices&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;select&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;div&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;text-block&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;reader&amp;#34;&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;line&amp;#34;&lt;/span&gt;&amp;gt;Learning to code is a never-ending journey.&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;span&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;line&amp;#34;&lt;/span&gt;&amp;gt;Technologies evolve rapidly, requiring constant adaptation.&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;span&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;line&amp;#34;&lt;/span&gt;&amp;gt;JavaScript, HTML, and CSS are essential tools for web development.&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;span&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;line&amp;#34;&lt;/span&gt;&amp;gt;Frameworks like React and Vue enhance front-end capabilities.&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;span&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;line&amp;#34;&lt;/span&gt;&amp;gt;Back-end skills with Node.js extend JavaScript to the server.&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;span&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;div&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;progress&amp;#34;&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;progressText&amp;#34;&lt;/span&gt;&amp;gt;0/0&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;span&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;bar&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#7a8478&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;bar-fill&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#d699b6;font-weight:bold&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;bar&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;div&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;div&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;div&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;body&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#7a8478&#34;&gt;html&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;-css-样式&#34;&gt;🎨 CSS 样式&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d6cbb4;background-color:#252b2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;body&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;font-family&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;sans-serif&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;margin&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;0&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;padding&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;rem&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;background&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;#f0f4f8&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;color&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;#333&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;h1&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;text-align&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;center&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;margin-bottom&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;rem&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.toolbar {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;display&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;flex&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;justify-content&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;center&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;flex-wrap&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;wrap&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;gap&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;rem&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;margin-bottom&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;rem&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.toolbar &lt;span style=&#34;color:#7a8478&#34;&gt;button&lt;/span&gt;&lt;span style=&#34;color:#7a8478&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.toolbar &lt;span style=&#34;color:#7a8478&#34;&gt;select&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;padding&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;0.6&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;rem&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;1.2&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;rem&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;border-radius&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;px&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;border&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;none&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;font-size&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;rem&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.toolbar &lt;span style=&#34;color:#7a8478&#34;&gt;button&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;background&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;#0077cc&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;color&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;white&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;cursor&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;pointer&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.toolbar &lt;span style=&#34;color:#7a8478&#34;&gt;button&lt;/span&gt;:disabled {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;background&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;#ccc&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;cursor&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;not-allowed&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.text-block {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;background&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;white&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;padding&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;1.5&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;rem&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;border-radius&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;6&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;px&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;box-shadow&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;px&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;6&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;px&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;rgba&lt;/span&gt;(&lt;span style=&#34;color:#d699b6&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#d699b6&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#d699b6&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#d699b6&#34;&gt;0.1&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.line {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;display&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;block&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;margin-bottom&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;rem&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;cursor&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;pointer&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;transition&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;background&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;0.3&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;s&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.line:hover {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;background&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;#f9f9f9&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.line.active {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;background&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;#fff3cd&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;font-weight&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;bold&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.progress {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;text-align&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;center&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;margin-top&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;rem&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.bar {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;height&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;8&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;px&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;width&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;100&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;%&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;background&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;#eee&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;border-radius&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;px&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;overflow&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;hidden&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.bar-fill {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;height&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;100&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;%&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;width&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;0&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;background&lt;/span&gt;: &lt;span style=&#34;color:#d699b6&#34;&gt;linear-gradient&lt;/span&gt;(&lt;span style=&#34;color:#e67e80&#34;&gt;to&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;right&lt;/span&gt;, &lt;span style=&#34;color:#d699b6&#34;&gt;#0077cc&lt;/span&gt;, &lt;span style=&#34;color:#d699b6&#34;&gt;#005fa3&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;transition&lt;/span&gt;: &lt;span style=&#34;color:#e67e80&#34;&gt;width&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;0.3&lt;/span&gt;&lt;span style=&#34;color:#dbbc7f&#34;&gt;s&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;-javascript逻辑&#34;&gt;💡 JavaScript逻辑&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d6cbb4;background-color:#252b2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; lines &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;document&lt;/span&gt;.querySelectorAll(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;.line&amp;#39;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; playBtn &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;document&lt;/span&gt;.getElementById(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;start&amp;#39;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; pauseBtn &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;document&lt;/span&gt;.getElementById(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;pause&amp;#39;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; resumeBtn &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;document&lt;/span&gt;.getElementById(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;resume&amp;#39;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; stopBtn &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;document&lt;/span&gt;.getElementById(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;stop&amp;#39;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; resetBtn &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;document&lt;/span&gt;.getElementById(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;reset&amp;#39;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; voiceSelect &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;document&lt;/span&gt;.getElementById(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;voices&amp;#39;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; progressText &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;document&lt;/span&gt;.getElementById(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;progressText&amp;#39;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; progressBar &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;document&lt;/span&gt;.getElementById(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; synth &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;window&lt;/span&gt;.speechSynthesis;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;let&lt;/span&gt; voices &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; [];&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;let&lt;/span&gt; currentIndex &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;0&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;let&lt;/span&gt; currentUtterance &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;null&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;let&lt;/span&gt; isPaused &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;false&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;function&lt;/span&gt; populateVoices() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  voices &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; synth.getVoices();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  voiceSelect.innerHTML &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  voices.forEach((voice, index) =&amp;gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; opt &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;document&lt;/span&gt;.createElement(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;option&amp;#39;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    opt.value &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; index;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    opt.textContent &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b2c98f&#34;&gt;`&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;${&lt;/span&gt;voice.name&lt;span style=&#34;color:#b2c98f&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt; (&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;${&lt;/span&gt;voice.lang&lt;span style=&#34;color:#b2c98f&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;)`&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    voiceSelect.appendChild(opt);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  });&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;synth.onvoiceschanged &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; populateVoices;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;populateVoices();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;function&lt;/span&gt; updateUI() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  progressText.textContent &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b2c98f&#34;&gt;`&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;${&lt;/span&gt;currentIndex &lt;span style=&#34;color:#7a8478&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;${&lt;/span&gt;lines.length&lt;span style=&#34;color:#b2c98f&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;`&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  progressBar.style.width &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b2c98f&#34;&gt;`&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;${&lt;/span&gt;((currentIndex &lt;span style=&#34;color:#7a8478&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#7a8478&#34;&gt;/&lt;/span&gt; lines.length) &lt;span style=&#34;color:#7a8478&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;100&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;%`&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;function&lt;/span&gt; highlightLine(index) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  lines.forEach((line, i) =&amp;gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    line.classList.toggle(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;active&amp;#39;&lt;/span&gt;, i &lt;span style=&#34;color:#7a8478&#34;&gt;===&lt;/span&gt; index);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  });&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  lines[index]&lt;span style=&#34;color:#7a8478&#34;&gt;?&lt;/span&gt;.scrollIntoView({ behavior&lt;span style=&#34;color:#7a8478&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;smooth&amp;#39;&lt;/span&gt;, block&lt;span style=&#34;color:#7a8478&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;center&amp;#39;&lt;/span&gt; });&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;function&lt;/span&gt; speakLine(index) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;if&lt;/span&gt; (index &lt;span style=&#34;color:#7a8478&#34;&gt;&amp;gt;=&lt;/span&gt; lines.length) &lt;span style=&#34;color:#e67e80&#34;&gt;return&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; text &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; lines[index].textContent;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; utter &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;new&lt;/span&gt; SpeechSynthesisUtterance(text);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; selected &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; voiceSelect.value;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;if&lt;/span&gt; (voices[selected]) utter.voice &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; voices[selected];&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  utter.rate &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;1&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  utter.onstart &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; () =&amp;gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    highlightLine(index);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    playBtn.disabled &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;true&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pauseBtn.disabled &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;false&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    resumeBtn.disabled &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;true&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    stopBtn.disabled &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;false&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  };&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  utter.onend &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; () =&amp;gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e67e80&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#7a8478&#34;&gt;!&lt;/span&gt;isPaused) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      currentIndex&lt;span style=&#34;color:#7a8478&#34;&gt;++&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#e67e80&#34;&gt;if&lt;/span&gt; (currentIndex &lt;span style=&#34;color:#7a8478&#34;&gt;&amp;lt;&lt;/span&gt; lines.length) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        speakLine(currentIndex);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      } &lt;span style=&#34;color:#e67e80&#34;&gt;else&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        resetControls();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  };&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  currentUtterance &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; utter;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  synth.speak(utter);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  updateUI();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;function&lt;/span&gt; resetControls() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  playBtn.disabled &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;false&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  pauseBtn.disabled &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;true&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  resumeBtn.disabled &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;true&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  stopBtn.disabled &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;true&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;playBtn.onclick &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; () =&amp;gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  currentIndex &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;0&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  speakLine(currentIndex);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pauseBtn.onclick &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; () =&amp;gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  synth.pause();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  isPaused &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;true&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  pauseBtn.disabled &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;true&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  resumeBtn.disabled &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;false&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;resumeBtn.onclick &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; () =&amp;gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  synth.resume();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  isPaused &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;false&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  pauseBtn.disabled &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;false&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  resumeBtn.disabled &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;true&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;stopBtn.onclick &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; () =&amp;gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  synth.cancel();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  resetControls();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;resetBtn.onclick &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; () =&amp;gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  synth.cancel();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  currentIndex &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;0&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  highlightLine(currentIndex);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  updateUI();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lines.forEach((line, index) =&amp;gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  line.addEventListener(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;click&amp;#39;&lt;/span&gt;, () =&amp;gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    synth.cancel();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    currentIndex &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; index;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    speakLine(currentIndex);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  });&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;});&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;updateUI();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;-它们如何工作&#34;&gt;✅ 它们如何工作&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;每一个句子都是&lt;code&gt;&amp;lt;span class=&amp;quot;sentence&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;我们迭代句子并使用&lt;code&gt;SpeechSynthesisUtterance&lt;/code&gt;大声朗读&lt;/li&gt;&#xA;&lt;li&gt;在朗读过程中，高亮正确的文本并滚动&lt;/li&gt;&#xA;&lt;li&gt;一个句子结束后，自动朗读下一个句子&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;-尾声&#34;&gt;🔚 尾声&lt;/h2&gt;&#xA;&lt;p&gt;阅读了本文，你理解了：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;浏览器TTS的运行原理&lt;/li&gt;&#xA;&lt;li&gt;如何实现动态高亮文本&lt;/li&gt;&#xA;&lt;li&gt;如何从零构建一个功能齐全的阅读界面&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;你可以扩展项目功能：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;在&lt;code&gt;localStorage&lt;/code&gt;保存阅读进度&lt;/li&gt;&#xA;&lt;li&gt;添加进度条&lt;/li&gt;&#xA;&lt;li&gt;加载外部文章或用户输入&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
    <item>
      <title>osu!APIv1请求示例</title>
      <link>https://blog.verdant.ee/posts/osu-apiv1%E8%AF%B7%E6%B1%82%E7%A4%BA%E4%BE%8B/</link>
      <pubDate>Fri, 11 Apr 2025 22:29:23 +0000</pubDate><author>i@glowisle.me (五葉地錦)</author>
      <guid>https://blog.verdant.ee/posts/osu-apiv1%E8%AF%B7%E6%B1%82%E7%A4%BA%E4%BE%8B/</guid>
      <description>&lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;&#xA;&lt;p&gt;本文章使用Nodejs环境做演示。请求用户数据。代码中的APIKEY要在&lt;a href=&#34;https://osu.ppy.sh/home/account/edit&#34;&gt;osu官网‬&lt;/a&gt;申请。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d6cbb4;background-color:#252b2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; API_URL &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;osu.ppy.sh&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; init &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    k&lt;span style=&#34;color:#7a8478&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;YOUR_API_KEY&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    type&lt;span style=&#34;color:#7a8478&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    u&lt;span style=&#34;color:#7a8478&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;kyzzz5658&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; https &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#859289;font-style:italic&#34;&gt;// 将参数序列化为查询字符串&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; query &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;new&lt;/span&gt; URLSearchParams(init);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; options &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    hostname&lt;span style=&#34;color:#7a8478&#34;&gt;:&lt;/span&gt; API_URL,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    method&lt;span style=&#34;color:#7a8478&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    path&lt;span style=&#34;color:#7a8478&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#b2c98f&#34;&gt;`/api/get_user?&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;${&lt;/span&gt;query&lt;span style=&#34;color:#b2c98f&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;`&lt;/span&gt; &lt;span style=&#34;color:#859289;font-style:italic&#34;&gt;// 附加参数&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; req &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; https.request(options, (res) =&amp;gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e67e80&#34;&gt;let&lt;/span&gt; data &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    res.on(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;data&amp;#39;&lt;/span&gt;, (chunk) =&amp;gt; data &lt;span style=&#34;color:#7a8478&#34;&gt;+=&lt;/span&gt; chunk);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    res.on(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;end&amp;#39;&lt;/span&gt;, () =&amp;gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e67e80&#34;&gt;try&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            console.log(JSON.parse(data[&lt;span style=&#34;color:#d699b6&#34;&gt;0&lt;/span&gt;].username));&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        } &lt;span style=&#34;color:#e67e80&#34;&gt;catch&lt;/span&gt; (e) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            console.error(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;JSON 解析失败:&amp;#39;&lt;/span&gt;, e);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    });&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;});&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#859289;font-style:italic&#34;&gt;// 错误处理&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;req.on(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;error&amp;#39;&lt;/span&gt;, (err) =&amp;gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    console.error(&lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#39;请求失败:&amp;#39;&lt;/span&gt;, err.code);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;});&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;输出：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d6cbb4;background-color:#252b2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    user_id: &amp;#39;33932276&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    username: &amp;#39;Kyzzz5658&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    join_date: &amp;#39;2023-06-24 08:48:13&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    count300: &amp;#39;2139&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    count100: &amp;#39;609&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    count50: &amp;#39;194&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    playcount: &amp;#39;44&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ranked_score: &amp;#39;1917044&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    total_score: &amp;#39;3095639&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pp_rank: &amp;#39;1968010&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    level: &amp;#39;8.0115&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pp_raw: &amp;#39;43.5449&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    accuracy: &amp;#39;81.70417785644531&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    count_rank_ss: &amp;#39;0&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    count_rank_ssh: &amp;#39;0&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    count_rank_s: &amp;#39;0&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    count_rank_sh: &amp;#39;0&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    count_rank_a: &amp;#39;1&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    country: &amp;#39;CN&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    total_seconds_played: &amp;#39;2259&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pp_country_rank: &amp;#39;38721&amp;#39;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    events: []&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;​&#x9;&lt;a href=&#34;https://github.com/ppy/osu-api/wiki&#34;&gt;首页 ·ppy/osu-api 维基&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Nodejs环境下控制台拼接字符串输出有undefind</title>
      <link>https://blog.verdant.ee/posts/nodejs%E7%8E%AF%E5%A2%83%E4%B8%8B%E6%8E%A7%E5%88%B6%E5%8F%B0%E6%8B%BC%E6%8E%A5%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%BE%93%E5%87%BA%E6%9C%89undefind/</link>
      <pubDate>Sat, 22 Mar 2025 18:56:33 +0000</pubDate><author>i@glowisle.me (五葉地錦)</author>
      <guid>https://blog.verdant.ee/posts/nodejs%E7%8E%AF%E5%A2%83%E4%B8%8B%E6%8E%A7%E5%88%B6%E5%8F%B0%E6%8B%BC%E6%8E%A5%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%BE%93%E5%87%BA%E6%9C%89undefind/</guid>
      <description>&lt;p&gt;今天在Nodejs环境下搓小工具，控制台输出拼接字符串时，发现有&lt;code&gt;undefind&lt;/code&gt;，代码如下：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d6cbb4;background-color:#252b2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; date &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e67e80&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#d699b6&#34;&gt;Date&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; year &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; date.getFullYear();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; month &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; date.getMonth();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; day &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; date.getDate();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; hour &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; date.getHours();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; minute &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; date.getMinutes();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; second &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; date.getSeconds();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;const&lt;/span&gt; logTime &lt;span style=&#34;color:#7a8478&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b2c98f&#34;&gt;`[&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;${&lt;/span&gt;year&lt;span style=&#34;color:#b2c98f&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;${&lt;/span&gt;month&lt;span style=&#34;color:#b2c98f&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;${&lt;/span&gt;day&lt;span style=&#34;color:#b2c98f&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;${&lt;/span&gt;hour&lt;span style=&#34;color:#b2c98f&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;${&lt;/span&gt;minute&lt;span style=&#34;color:#b2c98f&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;${&lt;/span&gt;second&lt;span style=&#34;color:#b2c98f&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b2c98f&#34;&gt;] `&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;class&lt;/span&gt; GenerateLog {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;static&lt;/span&gt; log() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    process.stdout.write(logTime);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;console.log(GenerateLog.log() &lt;span style=&#34;color:#7a8478&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;log output on the console&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;输出确是这样：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d6cbb4;background-color:#252b2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[2025-3-22 18:56:33] undefindlog output on the console&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;原因&#xA;：&lt;code&gt;GenerateLog.log()&lt;/code&gt;方法没有返回值，所以输出&lt;code&gt;undefind&lt;/code&gt;，解决方法如下：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#d6cbb4;background-color:#252b2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#859289;font-style:italic&#34;&gt;// 让log方法返回logTime&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e67e80&#34;&gt;class&lt;/span&gt; GenerateLog {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e67e80&#34;&gt;static&lt;/span&gt; log() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e67e80&#34;&gt;return&lt;/span&gt; logTime; &lt;span style=&#34;color:#859289;font-style:italic&#34;&gt;// 返回字符串&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;console.log(GenerateLog.log() &lt;span style=&#34;color:#7a8478&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#b2c98f&#34;&gt;&amp;#34;log output on the console&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;关键总结：&#xA;Javascript中，如果方法没有返回值，那么输出的就是&lt;code&gt;undefind&lt;/code&gt;&lt;/p&gt;&#xA;&lt;h4 id=&#34;扩展&#34;&gt;扩展&lt;/h4&gt;&#xA;&lt;p&gt;为什么 console.log() 本身会返回 undefined？&#xA;在 REPL 环境（如 Node.js 命令行或浏览器控制台）中，每条语句的执行结果会被隐式打印。由于 console.log() 函数本身没有返回值（即返回 undefined），因此会显示 undefined。但在脚本执行时，这一行为不会发生，因为脚本模式不自动打印返回值&lt;/p&gt;&#xA;</description>
    </item>
  </channel>
</rss>
