Yu Jung-Yu
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.

      Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Explore these features while you wait
      Complete general settings
      Bookmark and like published notes
      Write a few more notes
      Complete general settings
      Write a few more notes
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # 瀏覽器 Console 偵錯完全指南 ## 📖 前言:告別 F12 亂 Try 你是否也常遇到這種情況:明明寫了 CSS,畫面卻不如預期?或是想用 JavaScript 抓取元素,卻一直回傳 `null`? 多數人會按 F12,在「Elements (元素)」面板上點來點去,靠「肉眼」逐行比對。這就像隔著毛玻璃看問題,耗時且令人脾氣暴躁。 這篇指南將帶您解鎖一個更強大的工具:**Console (主控台)**。 Console 不只是一個顯示錯誤訊息的地方,它是一個**即時、互動的 JavaScript 實驗室**。你可以在這裡直接「存取」並「修改」當前的網頁,像外科手術般精準地找出病灶。 --- ## ⚠️ 安全第一:請勿貼上來路不明的程式碼 在開始前,您必須知道「Self-XSS」攻擊。駭客會欺騙您在 Console 貼上一段程式碼,聲稱能開啟隱藏功能,實則竊取您的帳號。 **黃金法則:永遠不要執行任何您不完全理解的程式碼。** --- ## 第一章:核心武器庫 ### 1.1 為什麼 Console 比 Elements 面板更強大? - **Elements (元素) 面板**:讓您「**看**」。您可以看到 HTML 結構和 CSS 規則。 - **Console (主控台)**:讓您「**做**」。您可以在此執行 JavaScript,動態地「**抓取**」、「**修改**」和「**測試**」任何元素。 ### 1.2 串連兩個世界的橋樑:`$0` `$0` 是一個神奇的變數,它會自動指向**您當前在「Elements」面板中選取的那個元素**。 **標準作業流程 (SOP):** 1. 在網頁上對著您想檢查的元素按右鍵,選「檢查」 2. 此時「Elements」面板會自動高亮該元素的 HTML 標籤 3. 切換到旁邊的「Console」面板 4. 輸入 `$0` 並按下 Enter Console 就會回傳該 DOM 元素物件。**這是我們所有診斷的起點。** ### 1.3 快速選取器:`$` 和 `$$` 在 Console 中快速選取元素的快捷鍵: #### `$$('CSS 選擇器')` - **功能:** 等同於 `document.querySelectorAll()` - **用途:** 抓取頁面上「**所有**」匹配的元素,並以陣列 (NodeList) 回傳 - **範例:** ```javascript // 抓取頁面上所有 class 為 .product-item 的元素 $$('.product-item') // 抓取所有圖片 $$('img') ``` #### `$('CSS 選擇器')` - **功能:** 等同於 `document.querySelector()` - **用途:** 抓取頁面上「**第一個**」匹配的元素 - **範例:** ```javascript // 抓取 ID 為 main-nav 的元素 $('#main-nav') ``` ### 1.4 進階輸出工具 - `console.log()` / `warn()` / `error()`:印出不同層級的訊息 - **`console.table()`**:將數據以表格呈現,便於「橫向比較」 - **`console.group()`**:將訊息分組,讓報告「可折疊」、更清晰 - **`console.dir()`**:印出可互動的 DOM 物件,而不只是 HTML 字串 --- ## 第二章:DOM 結構偵錯實戰 DOM (文件物件模型) 就是 HTML 的結構樹。結構一錯,版面就會全亂。 ### 2.1 【入門】我的 JavaScript 為什麼抓不到元素? **情境:** 您寫了 `document.getElementById('my-btn').click()` 但報錯,您懷疑元素根本沒載入或 ID 寫錯了。 **診斷(使用 `$$`):** ```javascript // 測試 ID 選擇器 $$('#my-btn').length // 如果回傳 0,代表 ID 寫錯了,或是元素真的不存在 // 測試 class 選擇器 $$('.important-item').length // 如果回傳 5,您就知道頁面上有 5 個 ``` **解說:** 這能讓您在 1 秒內知道是您的「選擇器語法」有錯,還是「DOM 結構」有錯。 ### 2.2 【實戰】我的元素為什麼跑版了? **情境:** 一個 `<div>` 應該要被包在 ID 為 `#sidebar` 的容器裡,但它跑到外面了。 **診斷(使用 `$0`):** 1. 在 Elements 面板點選那個跑版的 `<div>` 2. 切換到 Console,開始「爬樹」: ```javascript // 它是誰? $0 // 它的父元素是誰? $0.parentElement // 一看,發現父元素是 <body>,而不是 #sidebar,馬上抓到問題! // 它的下一個兄弟元素是誰? $0.nextElementSibling // 它的上一個兄弟元素是... $0.previousElementSibling ``` **解說:** `$0.parentElement` 是最常用的指令,90% 的「跑版」問題都能用它來確認父子關係是否如預期。 ### 2.3 【進階】快速狀態快照 當您需要快速了解當前頁面的「健康指數」: ```javascript console.clear(); const snapshotReport = { "圖示容器數量": document.querySelectorAll('[class*="_Layer-icon_"]').length, "Layer 項目數量": document.querySelectorAll('[class*="Layer-"]').length, "已替換圖示": document.querySelectorAll('[data-custom-icon-replaced]').length, "所有 SVG 元素": document.querySelectorAll('svg').length }; console.table(snapshotReport); ``` ### 2.4 【專家級】複雜 DOM 結構全面分析 **情境:** 您正在處理一個複雜的樹狀結構(例如檔案總管、圖層面板),想要全面了解整個結構的階層關係、樣式配置和互動元素分佈。 **診斷(深度結構掃描):** 這個腳本展示了如何系統化地分析複雜的 DOM 結構,特別適合用於偵錯樹狀元件。 ```javascript console.clear(); console.log('Checking Outline DOM structure...\n'); // 1. 智能尋找容器(容錯機制) var outline = document.querySelector('[class*="Outline"]'); if (!outline) { outline = document.querySelector('[class*="LayerTree"]'); } if (outline) { console.log('✅ Found Outline container'); console.log('className:', outline.className); // 2. 統計所有 Layer 元素 var layerRoots = outline.querySelectorAll('[class*="_Layer_"]'); console.log('\nTotal Layer elements found:', layerRoots.length); // 3. 深度分析前 5 個 Layer console.log('\n📊 First 5 Layers (詳細分析):'); for (var i = 0; i < Math.min(5, layerRoots.length); i++) { var layer = layerRoots[i]; var text = layer.textContent.trim().substring(0, 30); var style = window.getComputedStyle(layer); var children = layer.querySelectorAll('[class*="_Layer_"]'); console.log('\n' + (i + 1) + '.'); console.log(' Text:', text); console.log(' Tag:', layer.tagName); console.log(' Class:', layer.className); console.log(' padding-left:', style.paddingLeft); console.log(' Children count:', children.length); } // 4. 檢查互動元素(可點擊按鈕) console.log('\n\n🖱️ Checking clickable buttons:'); var clickables = outline.querySelectorAll('[class*="Layer-clickable"]'); console.log('Total clickable buttons:', clickables.length); for (var j = 0; j < Math.min(3, clickables.length); j++) { var btn = clickables[j]; var btnText = btn.textContent.trim().substring(0, 30); var style2 = window.getComputedStyle(btn); console.log('\n' + (j + 1) + '.'); console.log(' Text:', btnText); console.log(' padding-left:', style2.paddingLeft); } } else { console.error('❌ ERROR: Outline container not found'); console.log('💡 建議:檢查選擇器是否正確,或頁面是否已完全載入'); } ``` **解說:** 這個腳本展示了「專業級」DOM 分析的四個關鍵步驟: 1. **容錯機制**:使用 `if (!outline)` 提供備用選擇器,確保在不同情況下都能找到容器 2. **統計總覽**:先取得整體數量,建立全局視角 3. **深度抽樣**:針對前幾個元素進行詳細分析(文字、標籤、class、樣式、子元素數量) 4. **互動元素檢查**:單獨分析可點擊元素,因為它們的樣式配置往往是問題來源 **實戰技巧:** - **為什麼用 `var` 而不是 `let/const`?** 在 Console 中使用 `var` 可以讓您重複執行腳本而不會出現「變數已宣告」的錯誤 - **為什麼使用 `Math.min(5, array.length)`?** 防止陣列長度不足時出現錯誤 - **如何快速調整抽樣數量?** 修改 `Math.min(5, ...)` 和 `Math.min(3, ...)` 中的數字即可 **何時使用這個腳本?** - 階層縮排不正確時(檢查 `padding-left` 是否與嵌套深度相關) - 元素數量異常時(總數與預期不符) - 互動功能失效時(檢查 clickable 元素是否存在) - 接手他人程式碼時(快速了解 DOM 結構) --- ## 第三章:CSS 樣式偵錯實戰 這是最常見、也最磨脾氣的環節。您寫的 CSS 規則為什麼無效? ### 3.1 【關鍵觀念】`getComputedStyle` vs `$0.style` - **`$0.style`**:只能讀取該元素的 *inline style* (寫在 `style="..."` 屬性裡的 CSS)。**99% 的情況下,這不是您要的。** - **`window.getComputedStyle($0)`**:**這才是神器。** 它可以讀取瀏覽器合併了所有 CSS 檔案、`!important`、inline 樣式後,**「最終計算」出來的樣式**。 ### 3.2 【入門】我的顏色為什麼沒套用? **情境:** 您在 CSS 檔案寫了 `.my-button { color: red; }`,但按鈕依然是藍色。 **診斷(使用 `getComputedStyle`):** 1. 在 Elements 面板點選該按鈕 2. 切換到 Console: ```javascript // 1. 取得 $0 最終的計算樣式 let styles = window.getComputedStyle($0); // 2. 檢查 'color' 屬性 console.log(styles.getPropertyValue('color')); // 結果回傳 "rgb(0, 0, 255)" 或 "blue",您就知道紅色被蓋掉了 // 3. 順便檢查其他樣式 console.log(styles.getPropertyValue('font-size')); console.log(styles.getPropertyValue('padding-left')); ``` **解說:** 這能讓您立刻知道是哪個規則勝出(高權重),而不是猜測您的 class 名稱是不是寫錯了。 ### 3.3 【實戰】Flex 佈局大亂鬥 **情境:** 您想讓一個區塊「水平置中」,所以您在**父容器**寫了 `display: flex;` 和 `justify-content: center;`,結果它卻「垂直置中」了! **診斷(找出元兇 `flex-direction`):** 1. 在 Elements 面板點選**父容器**(因為 flex 屬性是定義在父層) 2. 切換到 Console: ```javascript // 1. 取得父容器 ($0) 的最終樣式 let parentStyles = window.getComputedStyle($0); // 2. 檢查 display 和 justify-content console.log(parentStyles.getPropertyValue('display')); // 回傳 'flex' console.log(parentStyles.getPropertyValue('justify-content')); // 回傳 'center' // 3. 檢查關鍵的「軸向」屬性(找出元兇!) console.log(parentStyles.getPropertyValue('flex-direction')); // 啊哈!回傳 "column"! ``` **解說:** 一旦 `flex-direction` 變成了 `column`(垂直軸),「主軸」就從水平變成了垂直。 - `justify-content`(主軸對齊)就會變成控制「**垂直**」對齊 - `align-items`(交叉軸對齊)反而變成了控制「**水平**」對齊 您發現了問題:您的 `justify-content: center` 確實生效了,只是它在「垂直軸」上生效。 ### 3.4 【進階】即時測試修正 (Live Fix) **情境:** 承上題,您已經知道問題了。您想**立刻測試**您的修正方案是否有效。 **修正(使用 `$0.style` 強制覆蓋):** ```javascript // 您的目標是「水平置中」,在 "column" 軸向下,您該用 align-items $0.style.alignItems = 'center'; // 畫面立刻就水平置中了! // 您可能還想把垂直對齊改回「靠上」 $0.style.justifyContent = 'flex-start'; ``` **解說:** `$0.style.XXX = 'value'` 會在該元素上**強制加上 inline-style**。因為 inline-style 的權重很高,它幾乎能覆蓋掉所有來自 CSS 檔案的規則。 **終極手段(僅供測試):`!important`** ```javascript // 在 Console 中執行,用 'important' 覆蓋 'important' $0.style.setProperty('padding-left', '20px', 'important'); ``` **警告:** 這只該用於「測試」,請不要在您的正式程式碼中濫用 `!important`。 ### 3.5 【專家級】CSS 來源偵測 **情境:** 找出到底是哪個樣式在作祟。 ```javascript console.clear(); const firstLayer = document.querySelector('[class*="Layer-clickable"]'); if (firstLayer) { // 檢查目標元素 console.group('🎯 目標元素分析'); const allStyles = window.getComputedStyle(firstLayer); console.log(' inline style:', firstLayer.style.paddingLeft || '(無)'); console.log(' computed style:', allStyles.paddingLeft); console.log(' 是否為 !important:', allStyles.getPropertyPriority('padding-left') === 'important' ? '🔥 是' : '❌ 否'); console.dir(firstLayer); console.groupEnd(); // 檢查父元素鏈 console.group('🌳 父元素鏈分析'); let parent = firstLayer.parentElement; let level = 0; let parentData = []; while (parent && level < 5) { const parentStyles = window.getComputedStyle(parent); parentData.push({ '層級': `(父 ${level + 1})`, 'Class': (parent.className || '').substring(0, 50), 'display': parentStyles.display, 'flex-direction': parentStyles.flexDirection || 'N/A' }); parent = parent.parentElement; level++; } console.table(parentData); console.groupEnd(); } ``` --- ## 第四章:實用範例集錦 ### 4.1 找出頁面上所有「壞掉的圖片」 ```javascript // 1. 抓取所有 <img> let allImages = $$('img'); // 2. 篩選出有問題的(已載入完成,但自然寬度為 0) let brokenImages = Array.from(allImages).filter(img => { return img.complete && img.naturalWidth === 0; }); // 3. 用表格印出所有壞圖的 src console.table(brokenImages.map(img => ({ src: img.src }))); ``` ### 4.2 檢查網頁親和性 (Accessibility) 找出所有沒有 `alt`(替代文字)的圖片: ```javascript // 使用 CSS 選擇器 :not([alt]) let imagesWithoutAlt = $$('img:not([alt])'); console.log(`警告:發現 ${imagesWithoutAlt.length} 張圖片沒有 alt 屬性!`); console.log(imagesWithoutAlt); ``` ### 4.3 模擬 JavaScript 事件 ```javascript // 抓取按鈕並模擬點擊 $('#my-btn').click(); // 模擬在輸入框中輸入 let input = $('#my-input'); input.value = '測試文字'; // 注意:這不會觸發 React 等框架的 state 改變 ``` ### 4.4 DOM 差異對比 (Before vs. After) ```javascript console.clear(); console.log('🔍 對比 DOM 結構...\n'); const replacedIcon = document.querySelector('[data-custom-icon-replaced]'); const originalIcon = document.querySelector('[class*="_Layer-icon_"]:not([data-custom-icon-replaced])'); // 已替換的 console.group('✅ 已替換的圖示容器'); if (replacedIcon) { console.dir(replacedIcon); console.log('子元素標籤:', Array.from(replacedIcon.children).map(c => c.tagName)); } console.groupEnd(); // 原始的 console.group('❌ 原始的圖示容器'); if (originalIcon) { console.dir(originalIcon); console.log('子元素標籤:', Array.from(originalIcon.children).map(c => c.tagName)); } console.groupEnd(); ``` --- ## 第五章:動態與非同步偵錯 處理前端最棘手的問題:**時序 (Timing)**。 ### 5.1 非同步驗證(等待 React 渲染) 您的腳本可能在 React/Vue 渲染完成*之前*就執行了: ```javascript console.log('⏰ 腳本已啟動... 將在 3 秒後執行最終檢查...'); setTimeout(() => { console.clear(); console.group('⏰ 3 秒後的最終檢查'); // 檢查總覽 const replaced = document.querySelectorAll('[data-custom-icon-replaced]').length; const total = document.querySelectorAll('[class*="_Layer-icon_"]').length; console.log('✅ 已替換圖示:', replaced, '/', total); // 抽樣檢查第一個 const firstIcon = document.querySelector('[class*="_Layer-icon_"]'); if (firstIcon) { console.group('📦 第一個圖示容器檢查:'); console.log('有 data-custom-icon-replaced 屬性?', firstIcon.hasAttribute('data-custom-icon-replaced')); console.dir(firstIcon); console.groupEnd(); } console.groupEnd(); }, 3000); ``` ### 5.2 動態穩定性監控(偵測無限迴圈) DOM 元素是否在*持續增加*? ```javascript console.clear(); console.log('🔄 開始 10 秒穩定性監控...'); let count = 0; let countHistory = []; const checkInterval = setInterval(() => { count++; const replaced = document.querySelectorAll('[data-custom-icon-replaced]').length; const total = document.querySelectorAll('[class*="_Layer-icon_"]').length; countHistory.push(total); console.log(`${count}秒: 已替換 ${replaced} / 總數 ${total}`); if (count >= 10) { clearInterval(checkInterval); // 最終判斷 console.log('\n' + '='.repeat(50)); console.log('🎯 監控完成!最終診斷報告:'); const finalTotal = countHistory[countHistory.length - 1]; const isStable = finalTotal === countHistory[countHistory.length - 2]; console.log(`10秒計數歷史: [${countHistory.join(', ')}]`); if (finalTotal > 110) { console.error('❌ 失敗!數量超限,可能存在無限迴圈。'); } else if (!isStable) { console.warn('⚠️ 注意!數量未超限,但在最後一秒仍有波動。'); } else { console.log('✅ 數量正常且穩定。'); } console.log('='.repeat(50)); } }, 1000); ``` --- ## 總結:您的偵錯 SOP Console 偵錯的核心流程: 1. **鎖定 (Select):** 用 Elements 面板 + `$0` 鎖定元素 2. **診斷 (Inspect):** 用 `getComputedStyle` 檢查 CSS,用 `.parentElement` 檢查 DOM 3. **測試 (Test):** 用 `$0.style` 即時修改樣式,直到找出解法 4. **修復 (Fix):** 回到您的 VS Code 或編輯器中,永久修復它 下次再遇到磨脾氣的前端問題時,試試這套流程吧! --- ## 附錄:進階偵錯範例 ### 深度診斷:為什麼功能沒有執行? ```javascript console.clear(); console.log('🔍 開始詳細診斷...\n'); // 1. 收集現狀 const replacedAny = document.querySelectorAll('[data-custom-icon-replaced]'); console.log('🎯 替換狀態:'); console.log('已找到替換標記:', replacedAny.length, '個'); // 2. 抽樣檢查(前 5 個) console.groupCollapsed('📝 前 5 個組件的詳細資訊'); const layers = document.querySelectorAll('[class*="Layer-"]'); Array.from(layers).slice(0, 5).forEach((layer, index) => { const iconDiv = layer.querySelector('[class*="_Layer-icon_"]'); const textContent = (layer.textContent || '').trim(); const hasReplaced = iconDiv?.hasAttribute('data-custom-icon-replaced'); console.group(`${index + 1}. ${textContent.substring(0, 20)}`); console.log('已替換標記:', hasReplaced ? '✅ 是' : '❌ 否'); console.log('圖示容器 DOM:'); console.dir(iconDiv); console.groupEnd(); }); console.groupEnd(); // 3. 提出假說 if (replacedAny.length === 0) { console.warn('\n⚠️ 沒有任何圖示被替換!可能原因:'); console.log('1. replaceOutlineIcons 函數沒有執行'); console.log('2. 組件名稱匹配失敗'); console.log('3. 代碼沒有正確部署(需重啟 dev 伺服器)'); } // 4. 實驗驗證 console.group('\n🧪 測試手動替換第一個圖示'); const firstIcon = document.querySelector('[class*="_Layer-icon_"]'); if (firstIcon) { firstIcon.setAttribute('data-test-manual', 'true'); const hasTestAttr = firstIcon.hasAttribute('data-test-manual'); console.log('手動屬性設置成功:', hasTestAttr ? '✅ 是' : '❌ 否'); if (hasTestAttr) { console.log('✅ DOM 操作正常,問題出在 replaceOutlineIcons 邏輯'); } } console.groupEnd(); console.log('\n💡 建議: 請檢查 replaceOutlineIcons 的執行時機與邏輯。'); ``` **記住:永遠不要執行任何您不完全理解的程式碼。祝您偵錯順利!** 🎉

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Google Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully