核心步驟
- 取得 JSON 字串或物件 (AJAX 回應 / 內嵌變數)。
JSON.parse() 轉為 JS 物件/陣列 (若已是物件可跳過)。
$.each() 或 for...of 迭代。
- 拼裝 HTML 字串或建立 DOM 節點。
- 一次性
append()/html() 寫入容器,減少回流。
完整範例:檔案列表渲染
<table id="fileTable"><thead><tr><th>檔名</th><th>操作</th></tr></thead><tbody></tbody></table>
<script>
function renderFileList(jsonStr) {
if (!jsonStr) return;
let arr;
try { arr = JSON.parse(jsonStr); }
catch (e) { console.error('JSON 解析失敗', e); return; }
const $tbody = $('#fileTable tbody');
$tbody.empty(); // 清空舊資料
let html = '';
$.each(arr, function(idx, item) {
const name = decodeURIComponent(decodeURIComponent(item.name)); // 雙重解碼
html += `<tr>
<td><span class="name">${name}</span></td>
<td>
<button class="btn btn-sm btn-danger" data-storename="${item.storename}">刪除</button>
</td>
</tr>`;
});
$tbody.append(html);
}
// 事件代理:動態新增的按鈕也生效
$('#fileTable').on('click', '.btn-danger', function() {
if (confirm('確定刪除?')) {
$(this).closest('tr').remove();
// 可同步呼叫後端刪除 API
}
});
</script>
進階技巧
- 模板引擎:複雜結構改用
template.js、Handlebars 或 Vue/React 組件化。
- 虛擬清單:超大資料量 (>1000 行) 使用
clusterize.js 或原生 IntersectionObserver 實現虛擬滾動。
- XSS 防護:使用者輸入內容務必
text() 而非 html(),或經過 DOMPurify 淨化。
- 日期格式化:
dayjs(item.updateTime).format('YYYY-MM-DD HH:mm')。
常見錯誤
$.each(arr, function(i, v) { ... }) 中 this 指向 v,箭頭函式無 this 需用 v。
- 雙重
decodeURIComponent 處理 URL 編碼中文 (後端常 URLEncoder.encode 兩次)。
- 在迴圈中重複
append() 導致效能差,應累積字串最後一次寫入。