在 editArticle 函數中存在字符串拼接語法錯誤,導致整個 <script> 塊解析失敗,進而使頁面上所有 onclick="testButton()" 失效。
function editArticle(articleId){
window.location.href="/blog/article/editArticle.do?articleId="+articleId+"&randomCode="Math.random();
// ↑ 缺少 + 號 ↑ 字符串未閉合
}
<script> 時遇到語法錯誤testButton)未被註冊onclick="testButton()" 調用未定義函數 → 靜默失效(控制台報 ReferenceError: testButton is not defined)function editArticle(articleId){
window.location.href = "/blog/article/editArticle.do?articleId=" + articleId + "&randomCode=" + Math.random();
// ↑ 添加 + 號 ↑ 添加 + 號
}
function editArticle(articleId) {
try {
const baseUrl = "/blog/article/editArticle.do";
const params = new URLSearchParams({
articleId: articleId,
randomCode: Math.random().toString(36).substring(2) // 更短的隨機碼
});
window.location.href = baseUrl + "?" + params.toString();
} catch (e) {
console.error("跳轉失敗:", e);
// 降級方案
window.location.href = "/blog/article/editArticle.do?articleId=" + encodeURIComponent(articleId);
}
}
function testButton() {
alert("click");
}
// 現代事件綁定最佳實踐(替代內聯 onclick)
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('[data-action="test"]').forEach(btn => {
btn.addEventListener('click', testButton);
});
document.querySelectorAll('[data-action="delete"]').forEach(btn => {
btn.addEventListener('click', (e) => {
const articleId = e.target.dataset.articleId;
deleteArticle(e.target, articleId);
});
});
});
<!-- 替代 onclick="testButton()" -->
<button type="button" data-action="test">test</button>
<!-- 替代 onclick="deleteArticle(this,'...')" -->
<button type="button" data-action="delete" data-article-id="3822ff5c60d1428eb01f0bc9166bed9b">刪除</button>
SyntaxError 或 ReferenceErrordebugger; 斷點逐步執行| 反模式 | 問題 | 推薦模式 |
|---|---|---|
內聯 onclick="..." | 內容安全策略限制、難維護、作用域混亂 | addEventListener + data-* 屬性 |
| 字符串拼接 URL | 易漏符號、編碼問題、XSS 風險 | URLSearchParams + encodeURIComponent |
| 全局函數污染 | 命名衝突、難測試 | 模塊化 (ES6 Modules / IIFE) |
| 無錯誤邊界 | 單點故障導致整頁腳本失效 | try-catch 包裹關鍵邏輯 |