0. 快速入門
這個編輯器是什麼?
Event Flow 編輯器是 Social Stream Ninja 的「進階自動化」層。它位於簡單彈出視窗開關之上,讓您撰寫自己的路由邏輯。在需要以下功能時使用它:
- 在服務之間篩選並轉送聊天(例如將 Twitch 鏡像至 Discord,但封鎖命令)。
- 透過 AND/OR/NOT 邏輯建立以忠誠度為依據的命令、關鍵字遊戲或抽獎資格限制。
- 根據在流程中補充的資料,觸發自訂疊加畫面、音訊、OBS 場景或 webhook。
- 在單一自動化中混合多個平台(Kick + Twitch + YouTube 透過一個流程路由)。
可以將彈出視窗視為「快速預設」,將 Event Flow 視為自訂工作流程的工具集。
啟動和基礎知識
- 從主儀表板選單(桌面應用程式或擴充功能)開啟 Event Flow 編輯器。
- 每個專案在匯出前都儲存在本機。使用
Export以備份或分享。 - 在稱為以下名稱的畫布中工作: 流程。每個流程都可以同時訂閱多個平台。
節點速覽
- 輸入 (左側連接埠)接收訊息脈絡。
- 輸出 (右側連接埠)發出相同脈絡以及所有編輯。
- 邏輯節點可能同時發出
true頻道和可選的false頻道。
承載資料結構
每則訊息都帶有 JSON 物件。必要鍵遵循 docs/event-reference.html (platform、type、chatname、chatmessage 等)。將自訂資料附加至 meta.
每個流程都從觸發條件開始
動作節點(綠色)從不自行執行,只有上方的觸發條件節點(藍色)求值為以下結果時才觸發: true。僅將動作串聯起來的流程看似有效,但會一直閒置,因為沒有任何東西啟動該鏈。節點名稱描述的是節點 做什麼,而不是它何時發生: 精選訊息(Feature Message) 在流程抵達它時精選訊息,而不會在您於其他位置精選訊息時觸發。
Flow Actions 疊加畫面(動作輸出)
選擇 贊助:慶祝 + 語音 以使用現成的動畫和合成感謝語音片段,或使用進階的 贊助:動畫 + 聲音 + OBS 濾鏡 範本。新提醒範本初始為停用狀態,讓您可以先設定並測試。對於 OBS 範本,在兩個濾鏡動作中選擇同一個來源和同一個通常關閉的濾鏡。
選擇 播放音訊剪輯 → 瀏覽聲音 搜索英语、西班牙语和巴西葡萄牙语的原始效果和预先录制的合成短语。按類別、事件、語言、交付或持續時間進行過濾;保存收藏夾並在選擇前在本地預覽 使用聲音。 聲音庫 也可以自行開啟並為自訂覆蓋提供聲音 URL。多重警報使用相同的瀏覽器。
在事件流中,使用加號按鈕建立一組隨機的兩到二十種聲音,然後選擇 使用隨機集。每個觸發器都會播放一種選定的聲音。選擇單一聲音或輸入另一個音訊 URL 會取代該群組。 播放選項 控制重疊、排隊和動作的冷卻時間; 停止音訊剪輯 停止 Flow Actions 剪輯並清除其佇列。限制付費命令時,在任何花費積分操作之前放置速率限制器。音訊播放不會自動退還單獨的積分費用。您仍然可以上傳錄音或選擇應用程式本機檔案。若要變更名稱或訊息,請使用 朗讀文字(Speak Text).
Event Flow 透過以下頁面播放: Flow Actions 瀏覽器來源;Multi-Alerts 透過自己的瀏覽器來源播放。對於同一事件,只在其中一個來源啟用聲音,以免重複播放。使用 Tab 移動至流程節點,按 Enter 或空白鍵編輯其屬性。
例如以下節點: 播放音訊片段, 顯示媒體疊加畫面,以及 OBS 控制項都需要一個繪製介面。該介面就是由以下位址提供的 Flow Actions 疊加畫面頁面: actions.html。讓它在直播軟體(OBS/Streamer.bot 瀏覽器停駐面板等)中保持執行,讓 Event Flow 動作有地方顯示。
- 開啟 Social Stream Ninja 主彈出視窗(從以下位置載入的視窗: popup.html 或擴充功能圖示)。
- 捲動至「Flow Actions」卡片。使用 [複製連結] 按鈕,或點擊卡片內的 URL。
- 連結類似於
https://socialstream.ninja/actions.html?session=YOURSESSION。將其貼到 OBS 瀏覽器來源(建議 1920×1080),或在任意疊加畫面瀏覽器中開啟。
- 在 Play Audio Clip 或 Display Media Overlay 動作中,點擊 選擇本機檔案.
- 點選 複製用於 OBS 的本機 Flow Actions URL 並使用產生的 localhost URL 代替代管的 Flow Actions URL。
- 保持 SSApp 執行。如果所選檔案移動了,請回到動作並點擊 重新連結.
Chrome 擴充功能本身無法提供磁碟檔案。沒有桌面輔助應用程式時,請使用 Upload 或代管 URL。請參閱 Event Flow 媒體檔案指南 了解完整設定。
載入後,該疊加畫面可以:
- 顯示由流程觸發的 GIPHY 或直接媒體 URL、文字和彩紙。
- 在本機播放聲音(TTS、音訊片段),讓觀眾聽到。
- 透過彈出視窗 Flow Actions 區段中的 WebSocket 設定與 OBS 通訊(場景切換、來源開關、GDI+/FreeType 文字更新、重播緩衝區等)。
- 瀏覽器來源 API: 僅在以下情況下可用:
actions.html在 OBS 瀏覽器來源內執行,帶有 進階存取層級(Advanced Access Level)。此處支援場景切換,錄製 / 直播 / 重播緩衝區動作也可以將它用作備援方式。 - OBS WebSocket: 建議使用,以實現一致的控制。Social Stream Ninja Flow Actions 使用 OBS 28+ 的 OBS WebSocket v5 API,並要求連接埠上提供現代請求集:
4455. - 密碼: 選用。僅在 OBS 伺服器要求驗證時,才將
&obspw=...加入 Flow Actions URL。 - 疊加畫面診斷: 附加
&obsdebug=1至以下頁面的 URL:actions.html如果希望在排查問題時,在疊加畫面上顯示一個小型即時 OBS 連接徽章。 - 設定文字來源(Set Text Source): 直接更新 OBS Text (GDI+) 和 Text (FreeType 2) 輸入,並支援 Event Flow 範本變數,例如
{counterValue}和{counterTarget}. - 舊版 4.x 安裝: 如果仍使用 obs-websocket 4.x / 連接埠
4444,在升級 OBS / obs-websocket 之前,來源 / 濾鏡 / 靜音 / 文字動作將無法運作。
請參閱專門的 OBS 控制指南 了解每個觸發條件、動作、設定步驟和經過測試的方案。
- 開啟 obs-websocket-test.html.
- 確認
GetVersion,GetCurrentProgramScene,以及GetSceneList成功。 - 在測試完整 Event Flow 自動化之前,先在那裡執行相應的動作檢查。
1. 什麼內容流經節點?
Event Flow 執行階段透過每條連線傳遞兩種內容:
- 承載資料 — 事件或訊息資料物件。
- 閘控訊號 — 一個 true/false 位元,告知下一個節點是否執行。
false 連接埠,位於 Condition 節點上)。這樣就能輕鬆建立備援邏輯,無需複製整個流程。
輸入需求
- 事件來源 (Twitch Message、Timers、Manual Trigger 等)忽略上游輸入,它們產生自己的承載資料,並始終發出
true除非節點本身出錯。 - 轉換和邏輯節點 讀取承載資料,並可重寫欄位、設定狀態,或將閘控訊號翻轉為
false. - 動作節點 僅在閘控保持以下值時觸發:
true。如果您希望繼續串聯動作,它們仍可輸出更新後的承載資料。
輸出模式
單一輸出
大多數節點提供一個輸出。進入的內容(承載資料 + 閘控)會原樣輸出,除非節點對其進行編輯。
True/False 輸出
Condition、Compare、Regex 和 Logic 節點提供兩個輸出連接埠。 真(True) 透過綠色連接埠繼續; false 會在灰色/紅色連接埠提供。
直通與覆寫
部分節點(Set Variable、Math、Text Replace)會修改承載資料,但仍轉送 true/false 來自輸入的狀態。其他節點(NOT、AND、OR)自行重新計算布林值。
2. 邏輯節點速查
這些區塊解答最常見的「true/false 是什麼意思?」問題。
非(NOT)
- 輸入:來自前一節點的 1 個布林值(true/false)。
- 輸出:反轉後的布林值,以及未改動的承載資料。
- 預設行為: 如果 NOT 輸入沒有連接任何內容,它會求值為
false,因此輸出為true.
且(AND)
- 輸入:兩個或更多布林訊號(A、B 等)。可讓額外連接埠留空。
- 輸出:
true僅當所有連接輸入都等於true. - 當多個條件必須同時滿足時使用 AND(「是訂閱者」 和 「聊天訊息包含 !raffle」)。
OR
- 發出
true如果 任意 連接的輸入為 true。 - 適合多平台觸發條件:將 Twitch 和 YouTube 訊息節點接入單一 OR,然後統一下游動作。
不需要。許多節點已經提供整合式篩選器(例如「Filter User Level」 + 「Contains Text」)。僅當內建選項無法涵蓋您的組合,或需要供其他分支共用的可重用邏輯連接點時,才使用 AND。
true。保持它連接至有意義的節點,或停用該節點,以免意外放行流程。
3. 微型流程範例
A. 除命令訊息外自動回覆
此處 Regex 節點發出 true ,條件是訊息為指令。我們將 false 連接埠接到回覆,因此一般聊天者會收到確認,而命令直接通過。
B. 使用 AND 要求多項檢查
AND 節點確保只有使用正確關鍵字的會員才會轉送至 Discord。兩個分支都將布林結果傳送至 AND 節點;承載資料來自 第一個分支 ,並繼續向下游傳遞。
C. 使用 NOT 節點封鎖重複提醒
State Check 在提醒遭靜音時輸出 true 。透過反轉該結果,NOT 節點確保僅在旗標為以下值時播放慶祝效果: false.
D. 隨機播放兩種聲音之一
AND 閘不可省略。 獨立的 NOT 會輸出 true 每當 RANDOM 閘閒置時,因此聲音 B 會在每則以下聊天訊息時播放: 不符合觸發條件的訊息。 將觸發器連接至 AND 的第二個輸入,可將聲音 B 限制為僅在訊息符合條件時播放。同一模式適用於任何二選一的動作組合,不限於音訊。
4. 防止回傳、循環和轉送回授
跨介面轉送聊天很有用,但如果監聽自己的輸出,就可能產生無限回傳。請遵循以下防護措施:
傳入觸發條件和傳出 Relay Chat 的目標都會區分
youtube 和 youtubeshorts。當訊息應抵達兩個變體時,使用兩個轉送動作。請參閱 YouTube Shorts 與 Event Flow.
回流是指傳送至目標聊天後又被擷取的訊息。目前 Relay Chat 動作會略過這些已識別的回流;沒有單獨的 No Reflections 核取方塊。如需隱藏或限制它們在停駐面板和疊加畫面中的顯示,請使用 回流篩選器(Reflection Filter) 動作,帶有 全部封鎖, 允許第一則,或 全部允許。這控制重新接收時的顯示,而不是傳送。請遵循 Twitch 和 YouTube 轉送教學 了解完整設定。
- 避免重複轉送系統。 使用等效的 Event Flow 路由時,請停用全域 Relay all,並檢查是否有其他服務橋接相同聊天。自訂中繼資料不能保證在經過平台聊天後仍保留。
- 使用 Debounce 或 Cooldown 節點 用於每 X 秒只應觸發一次的提醒。
- 有意識地中斷循環。 如果兩個分支相互輸入,請新增邏輯節點檢查狀態變數(「currentlyRelaying」),以便在旗標已設定時提前退出流程。
5. 輸入、輸出和實用問題
節點接收什麼?
- 完整訊息承載資料。
- 閘控位元(
true/false). - 節點明確請求的可選脈絡(狀態變數、計時器)。
什麼內容離開節點?
- 相同承載資料,除非節點對其進行編輯。
- 重新計算的閘控位元(邏輯節點)或直通位元(動作)。
- 大多數副作用(如傳送聊天)不會改變承載資料,但點數動作可以附加狀態欄位,例如
pointsTotal或pointsSpendError用於下游邏輯。
何時分支?
每當希望針對以下內容作出不同反應時: true 與 false。從所需的彩色輸出(綠色 = true,灰色/紅色 = false)拖曳連線至下一個節點。
false 輸出,流程就會在此結束。這非常適合篩選器(「封鎖所有未通過檢查的內容」),但別忘了連接 false 路徑,如果需要備援處理。
常見問答
- 每一對篩選器都必須使用 AND 嗎? 不需要。許多節點包含多項檢查(例如,基本 Message Filter 支援關鍵字 + 角色)。僅對進階組合,或合併來自不同節點的訊號時使用 AND。
- true/false 值如何抵達 NOT 節點? 任何具有綠色輸出的節點都會發出
true作為預設值。條件失敗時,它發出false。將該連線接入 NOT 以反轉結果。 - 節點傳回 false 時,仍能發出承載資料嗎? 可以。承載資料仍會透過 false 輸出傳遞;由您決定該分支應通向何處。
- 如何比對 TikTok Team 成員? 選擇 TikTok Team 成員(TikTok Team Member) 在 User Role 節點中。它識別傳入訊息中的 TikTok Fan Club/team 等級和徽章,不依賴 Main Chat Overlay 設定。
- How do I limit TikTok TTS to Team level 10 or higher? 選擇 Compare Property → TikTok Team Level, Greater or equal (>=),以及 10. Connect this and a From Source → TikTok condition to an 且(AND) node, then connect AND to 朗讀文字(Speak Text). This reads
meta.teamMemberLevel, which native TikTok connectors and Standard capture supply when numeric Fan Club data is available. Image-only badges cannot provide an exact level; messages without the field do not match. Use Test Flow → TikTok Team Level to try levels below and above your minimum. Disable any separate automatic TTS if this flow should be the only reader. - 每個 Speak Text 節點可以使用不同的語音嗎? 可以。在以下欄位中輸入提供者支援的語音名稱或 ID: 語音覆寫(Voice Override),或留空以使用 Flow Actions TTS 預設值。
6. 範本變數參考
多個動作節點(Show Text、Set Text Source、Send Message、Relay Chat、TTS Speak、Call Webhook、Print Thermal Label)支援 範本變數 在執行階段會被事件資料替換。用大括號包住變數名稱,例如 {username}.
核心變數(回溯相容)
| 變數 | 別名 | 說明 | 範例 |
|---|---|---|---|
{username} | {chatname} | 使用者的顯示名稱 | CoolViewer123 |
{message} | {chatmessage} | 聊天訊息文字 | 大家好! |
{source} | - | 平台名稱(首字母大寫) | Twitch, YouTube |
{type} | - | 平台名稱(原始值) | twitch, youtube |
{donation} | {hasDonation} | 贊助顯示標籤 | $5.00, 500 bits |
延伸變數
| 變數 | 說明 | 範例 |
|---|---|---|
{displayname} | 顯示名稱(備用欄位) | CoolViewer123 |
{donoValue} | 提供或估算的等值美元贊助金額;Event Flow 從標準化的以下欄位推導門檻: hasDonation 標籤,例如數值, $數值、數值 + 單位,或精簡的單位/數值格式。未知具名虛擬單位依 100 單位 = 0.01 美元換算;未定價的 TikTok 禮物依每份禮物一個金幣(每個 0.01 美元)計算。 {donationAmount} 是舊版別名 | 5.00 |
{event} | 事件類型識別碼 | cheer, raid, new_follower |
{membership} | 會員狀態 | MEMBERSHIP, new_sponsor |
{subtitle} | 補充脈絡 | 已加入會員 3 個月 |
{userid} | 使用者的平台 ID | 12345678 |
{chatimg} | 使用者頭像 URL | https://... |
{contentimg} | 附加的影像 URL | https://... |
{rewardTitle} | 來源提供頂層獎勵標題欄位時的獎勵名稱 | 醒目顯示我的訊息(Highlight My Message) |
{meta} | 結構化事件資料(JSON) | {"viewers":100} |
{counterValue} | 經過 Counter 或 Check Counter 步驟後的目前計數器值 | 12 |
{counterTarget} | 計數器目標值 | 30 |
{counterRemaining} | 計數器目標減去目前值,最小為 0 | 18 |
{USERNAME}, {Username},以及 {username} 都以相同方式運作。
Check Counter 提供 {counterValue}, {counterTarget},以及 {counterRemaining}.
範例範本
- 顯示文字(Show Text):
{username} just cheered {hasDonation}! - 設定 OBS 文字來源(Set OBS Text Source):
{username}: now {counterValue}, need {counterTarget} - 轉送聊天(Relay Chat):
[{source}] {username}: {message} - TTS:
{username} says {message} - 贊助提醒:
{username} donated {donation} - {subtitle} - 熱感標籤:
{username},換行,然後{donation}。請參閱 熱感印表機指南 了解印表機設定、固定尺寸標籤和完整流程。 - Discord 呼叫 Webhook:
{"content":"{message}","username":"{username}","avatar_url":"{chatimg}"}
{donation} 在一般聊天訊息中),預留位置會替換為空字串,而不是顯示字面的 {donation} 文字。
7. 最佳做法檢查表
- 命名並設定色彩: 為節點設定名稱和色彩,以便日後辨認各個分支。
- 使用內建模擬器測試 (Send Test Event),然後再將流程投入直播。
- 在來源附近集中邏輯。 儘早篩選,避免後續額外處理。
- 將重複記錄存入狀態節點。 使用計數器、開關和時間戳記避免重複提醒。
- 記載 meta 欄位。 當您新增自訂的
meta鍵時,請記載它們,讓疊加畫面和遠端用戶端保持一致。
8. 進一步探索
從 Stream Deck 或 API 執行自訂工作流程:具名觸發條件、入門範本、工作流程探索、額外資料、HTTP/WebSocket/P2P 範例和旋鈕手勢。
準備深入了解?
- 使用 狀態節點 (計數器、開關、計時器)來追蹤事件之間的脈絡。
- 組合 變數和邏輯 以建立佇列系統、抽獎或評分引擎。
- 接入 點數和獎勵 系統,讓觀眾可以主動觸發流程。
- 執行 SSApp 桌面應用程式? 解鎖 自訂 JavaScript 節點 用於內建節點未涵蓋的任意邏輯。
- 檢查 事件參考 了解所有平台的詳細承載資料文件。
本指南刻意設計為獨立文件,您可以複製到本機、為團隊調整,並繼續在編輯器中嘗試。
9. 自訂 JavaScript 僅限 SSApp / 桌面應用程式
Event Flow 編輯器中的兩個節點讓您撰寫在流程處理管線內執行的任意 JavaScript: 自訂程式碼(Custom Code) (觸發條件)和 執行自訂程式碼(Execute Custom Code) (動作)。當內建節點無法表達某種需求時,它們提供自訂途徑。
new Function() / eval()。透過以下入口開啟編輯器: SSApp 桌面應用程式 以啟用它們。在擴充功能模式中,節點顯示為灰色,並帶有標籤 「僅限桌面應用程式」.
Ctrl+S 或 Cmd+S 執行相同動作。Cancel 不會變更節點。
Custom Code — 觸發條件節點
拖曳 自訂程式碼(Custom Code) 來自 進階 群組,位於 觸發器 面板拖到畫布上。它充當閘控:僅當程式碼傳回以下值時流程才繼續: true.
true 或 false.function(message) { ... }必須傳回: 布林值 —
true 讓流程繼續, false 以停止它。可用: 物件
message (參見 訊息 API 如下),加上 convertCurrency(value, targetCurrency, source) 和 convertToUSD(value, source).
Execute Custom Code — 動作節點
拖曳 執行自訂程式碼(Execute Custom Code) 來自 整合 群組,位於 操作 面板。它可以修改訊息、封鎖訊息或附加供下游節點讀取的中繼資料。
function(message, result) { ... }應傳回: 物件或 Promise,合併至
result— 請參閱 結果 API.可用:
message (事件承載資料), result (目前流程結果狀態), printThermal(html, options),加上 convertCurrency(value, targetCurrency, source) 和 convertToUSD(value, source).
printThermal('<strong>' + message.chatname + '</strong>')。SSApp 透過原生 Windows 印表機 API 靜默將工作排入佇列,並使用這些已儲存設定。流程可以透過以下選項覆寫它們: { width: '58mm', marginLeft: '3mm', marginRight: '3mm', marginTop: '2mm', marginBottom: '2mm', feed: '3mm', marginType: 'printableArea' }。傳回 Promise 使 Event Flow 能夠等待提交並回報錯誤。
物件 message
兩個節點都以下列形式接收完整事件承載資料: message。以下欄位始終可用;平台專屬事件可能包含其他欄位。
| 欄位 | 資料型別 | 說明 | 範例 |
|---|---|---|---|
message.chatmessage | 字串 | 聊天訊息文字(可能包含 HTML) | "Hello stream!" |
message.chatname | 字串 | 傳送者的顯示名稱 | "CoolViewer" |
message.userid | 字串 | 平台使用者 ID | "12345678" |
message.type | 字串 | 來源平台(小寫) | "twitch", "youtube", "kick" |
message.hasDonation | 字串 | 存在時的格式化贊助字串 | "$5.00", "500 bits" |
message.donoValue | 數值 / 字串 | 來源提供時的等值美元贊助金額;有效的零值會予以採用。Event Flow 改用以下內容作為備援: currency.js 轉換標準化的 hasDonation 標籤用於門檻比較,包括 100 個未知具名單位 = 0.01 美元。它不會解析 chatmessage 文字來擷取贊助值。 | 5 |
message.event | 字串 | 事件類型識別碼 | "new_follower", "cheer", "raid" |
message.membership | 字串 | 適用時的會員狀態 | "MEMBERSHIP" |
message.subtitle | 字串 | 次要脈絡列 | "Member for 3 months" |
message.mod | 布林值 | 傳送者是管理員 | true |
message.subscriber | 布林值 | 傳送者是訂閱者 | true |
message.vip | 布林值 | 傳送者具有 VIP 身分 | true |
message.chatimg | 字串 | 使用者頭像 URL | "https://..." |
message.meta | 物件 | 附加至事件的任意結構化資料 | { viewers: 120 } |
convertCurrency(message.hasDonation, 'EUR', message.type) 將格式化的贊助標籤轉換為 EUR。它傳回數字,或 null 當不支援請求的目標貨幣時。轉換器使用 Social Stream Ninja 的內部近似匯率,不會聯繫外部匯率服務。
動作傳回的內容
從動作程式碼傳回一般物件。您包含的任何欄位都會合併至流程的 result 物件;省略的欄位保持目前值。
| 傳回欄位 | 資料型別 | 效果 |
|---|---|---|
modified | 布林值 | 設定 true 如果您變更了 message 欄位。告知下游節點承載資料已編輯。 |
message | 物件 | 將訊息(可能已修改)傳回,讓下游節點收到您的變更。 |
blocked | 布林值 | 設定 true 以防止訊息顯示或轉送。 |
return { modified: false, message };即使沒有變更任何內容,傳回
message 使它繼續流向下一個節點。
程式碼片段範例
將任一項複製到相應節點類型的 JavaScript Code 文字區域。
觸發條件程式碼片段 — 傳回 true 以繼續流程
!queue, !raffle, !enter).動作程式碼片段 — 傳回 { modified, message }
{meta}).完整範例 — VIP 功能請求機器人
該流程監聽 !feature <text> 來自訂閱者、VIP 或管理員的內容,將其重新格式化為功能請求,並轉送至第二個目標(例如 Discord)。
步驟 1 — Custom Code 觸發條件 (貼到觸發條件的 JavaScript Code 欄位):
步驟 2 — Execute Custom Code 動作 (貼到動作的 JavaScript Code 欄位):
步驟 3 — Relay Chat 動作:在動作後新增標準 Relay Chat 節點,並設定為指向 Discord(或其他)目標。此處無需自訂程式碼,重新格式化的 message.chatmessage 會自動流經。
!feature dark mode support,並確認 Relay Chat 目標收到重新格式化的字串。
安全注意事項
window 物件,以及 preload 指令碼提供的任何 API(例如 window.ninjafy)。請將匯入的流程檔案視為可執行程式碼,只匯入可信來源的流程。
- 沒有網路沙盒。 動作程式碼可以呼叫
fetch()。如果接受他人分享的流程,請在啟用前審核 JS。 - 錯誤會遭攔截。 程式碼中的執行階段錯誤會傳回
false(觸發條件)或不執行動作(動作),並記錄至 DevTools 主控台,流程不會當機。 - 語法錯誤也一樣。 類型為
SyntaxError的編譯錯誤也會以相同方式攔截。如果節點似乎沒有反應,請檢查 DevTools(F12)。