在開發 GASO 的過程中,我遇到了一個讓我困擾好幾天的問題:頁面佈局的尺寸問題。
前幾天,我一直想把頁面佈局弄得漂亮一點,讓地圖能夠完美地適應螢幕。但是,我發現自己對於各層容器與 SVG 的尺寸關係一直搞不定:
這些問題讓我在 CSS 和 JavaScript 之間來回修改,但始終無法找到問題的根源。
直到今天,我意識到一個重要的道理:
在沒有數據支持的情況下修改代碼,就像在黑暗中摸索。
與其繼續盲目地調整數值,不如先建立一個「觀察系統」,讓我能夠即時看到各個元素的尺寸變化。這樣一來,我就能:
於是,我決定先暫停佈局的修改,轉而開發一個「即時尺寸監控功能」。
我需要一個簡單但實用的 debug 工具,能夠:
我選擇將 debug 資訊固定在左上角,原因是:
為了讓 debug 資訊醒目且專業,我採用了「駭客風格」的設計:
.debug-info {
position: fixed;
top: 10px;
left: 10px;
background: rgba(0, 0, 0, 0.8); /* 黑色半透明背景 */
color: #00ff00; /* 綠色文字 */
padding: 10px;
border-radius: 5px;
font-family: monospace; /* 等寬字體 */
font-size: 12px;
z-index: 9999; /* 確保在最上層 */
border: 1px solid #00ff00; /* 綠色邊框 */
}
設計理由:
我設計了兩種更新觸發方式:
// 定期更新(每秒一次)
setInterval(updateDebugInfo, 1000);
// 視窗變化時立即更新
window.addEventListener("resize", updateDebugInfo);
為什麼需要兩種?
首先,在 <style>
區塊中添加 debug 資訊的樣式:
/* Debug 資訊樣式 */
.debug-info {
position: fixed;
top: 10px;
left: 10px;
background: rgba(0, 0, 0, 0.8);
color: #00ff00;
padding: 10px;
border-radius: 5px;
font-family: monospace;
font-size: 12px;
z-index: 9999;
border: 1px solid #00ff00;
}
.debug-info div {
margin: 2px 0;
}
在 <body>
標籤內,添加 debug 資訊的顯示區域:
<!-- Debug 資訊顯示 -->
<div class="debug-info" id="debugInfo">
<div>螢幕: <span id="screenWidth">-</span> x <span id="screenHeight">-</span></div>
<div>容器: <span id="containerWidth">-</span> x <span id="containerHeight">-</span></div>
<div>SVG: <span id="svgWidth">-</span> x <span id="svgHeight">-</span></div>
</div>
設計說明:
<span>
標籤來存放動態更新的數值-
,表示尚未載入寬度 x 高度
,清晰易讀在 JavaScript 區塊中,添加更新函數:
// --- Debug 資訊更新函數 ---
function updateDebugInfo() {
try {
// 取得各項尺寸
const screenWidth = window.innerWidth;
const screenHeight = window.innerHeight;
const containerWidth = graph ? graph.clientWidth : 0;
const containerHeight = graph ? graph.clientHeight : 0;
const svgWidth = zoomInner ? zoomInner.clientWidth : 0;
const svgHeight = zoomInner ? zoomInner.clientHeight : 0;
// 取得 DOM 元素
const screenWidthEl = document.getElementById("screenWidth");
const screenHeightEl = document.getElementById("screenHeight");
const containerWidthEl = document.getElementById("containerWidth");
const containerHeightEl = document.getElementById("containerHeight");
const svgWidthEl = document.getElementById("svgWidth");
const svgHeightEl = document.getElementById("svgHeight");
// 更新顯示內容
if (screenWidthEl) screenWidthEl.textContent = screenWidth + "px";
if (screenHeightEl) screenHeightEl.textContent = screenHeight + "px";
if (containerWidthEl) containerWidthEl.textContent = containerWidth + "px";
if (containerHeightEl) containerHeightEl.textContent = containerHeight + "px";
if (svgWidthEl) svgWidthEl.textContent = svgWidth + "px";
if (svgHeightEl) svgHeightEl.textContent = svgHeight + "px";
} catch (e) {
console.error("Debug 更新錯誤:", e);
}
}
// 定期更新 debug 資訊
setInterval(updateDebugInfo, 1000);
window.addEventListener("resize", updateDebugInfo);
重點說明:
安全檢查:
const containerWidth = graph ? graph.clientWidth : 0;
使用三元運算子確保元素存在,避免錯誤
錯誤處理:
try {
// 更新邏輯
} catch (e) {
console.error("Debug 更新錯誤:", e);
}
使用 try-catch
包裹,確保錯誤不會影響其他功能
條件更新:
if (screenWidthEl) screenWidthEl.textContent = screenWidth + "px";
檢查元素存在才更新,避免 null reference 錯誤
完成後,頁面左上角會顯示類似這樣的資訊:
┌─────────────────────────┐
│ 螢幕: 1710px x 1080px │
│ 容器: 1670px x 900px │
│ SVG: 1200px x 800px │
└─────────────────────────┘
有了這個工具後,我立刻發現了一些有趣的現象:
容器寬度 < 螢幕寬度
SVG 寬度 ≠ 容器寬度
renderGraph()
函數中的尺寸計算視窗變化時的延遲
問題:之前嘗試添加 debug 功能時,多次導致頁面載入失敗。
解決方案:
try-catch
包裹所有 debug 相關代碼// ❌ 錯誤做法:直接存取可能不存在的元素
const width = graph.clientWidth;
// ✅ 正確做法:先檢查元素是否存在
const width = graph ? graph.clientWidth : 0;
問題:什麼時候開始更新 debug 資訊?
考慮的方案:
最終方案:
// 定期更新(每秒一次)
setInterval(updateDebugInfo, 1000);
// 視窗變化時立即更新
window.addEventListener("resize", updateDebugInfo);
這樣既能觀察載入過程,又能即時回應變化。
初始版本:
螢幕寬度: 1710px
螢幕高度: 1080px
容器寬度: 1670px
容器高度: 900px
...
問題:太冗長,不易快速掃視
改進版本:
螢幕: 1710px x 1080px
容器: 1670px x 900px
SVG: 1200px x 800px
優點:
x
符號,符合尺寸表示習慣在沒有充分了解問題之前,不要急於修改代碼。建立觀察工具,讓問題自己「現形」。
「如果你無法測量它,你就無法改進它。」 - Peter Drucker
好的開發者工具能夠:
console.log
在添加新功能時,一定要考慮:
使用 try-catch
和條件檢查,讓代碼更健壯。
這次我學到了一個重要的教訓:
不要一次性添加太多功能。
之前我嘗試同時添加:
結果導致頁面完全無法載入。
正確的做法:
有了這個 debug 工具後,我可以:
觀察現有佈局的問題
測試不同的佈局方案
優化響應式設計
建立完整的開發者工具面板
記錄和分析
今天雖然沒有直接解決佈局問題,但我做了一件更重要的事:建立了診斷工具。
這個 debug 工具不僅幫助我診斷佈局問題,還能: